Results 1 to 3 of 3

Thread: Getting axis rescaler to work while rending chart via QwtPlotRenderer

  1. #1
    Join Date
    Nov 2006
    Location
    Dresden, Germany
    Posts
    81
    Thanks
    9
    Thanked 6 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Getting axis rescaler to work while rending chart via QwtPlotRenderer

    I use PlotRescaler to get my axis displayed proportionally, regardless of the plot size (currently I'm using the X-Axis as reference):

    Qt Code:
    1. PlotRescaler::PlotRescaler(QwtPlot * chart) :
    2. QwtPlotRescaler(chart->canvas())
    3. {
    4. setRescalePolicy(QwtPlotRescaler::Fitting);
    5. setAspectRatio(0.0);
    6. setAspectRatio(QwtPlot::yLeft, 1.0);
    7. }
    To copy to clipboard, switch view to plain text mode 

    When I resize my chart widget, the y-axis limits get updated accordingly to keep the aspect ratio.

    However, when I render my chart to bitmap/vector via QwtPlotRenderer, for example with:

    Qt Code:
    1. QPdfWriter pdfWriter( fname );
    2. pdfWriter.setPageSizeMM( sizeMM );
    3. pdfWriter.setTitle( title );
    4. pdfWriter.setPageMargins( QMarginsF() );
    5. pdfWriter.setResolution( resolution );
    6.  
    7. QPainter painter( &pdfWriter );
    8. renderer.render( m_chart, &painter, documentRect );
    To copy to clipboard, switch view to plain text mode 

    hereby using arbitrary target sizes that differ from the current screen ratio, the aspect ratio is not maintained. Apparently, the rescaler is not notified of the chart/plot layout dimension change during the rendering.

    Is there a workaround/easy fix for that or do I have to modify QwtPlotRenderer to manually apply the rescaling after the plot layout update?

    Thanks,
    Andreas
    Andreas

  2. #2
    Join Date
    Nov 2006
    Location
    Dresden, Germany
    Posts
    81
    Thanks
    9
    Thanked 6 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Getting axis rescaler to work while rending chart via QwtPlotRenderer

    Hi there,

    since there wasn't a single reply since last summer, this seems to be a rather unpopular feature :-)

    Anyway, diggin into the code I found no easy way to implement this - the current API doesn't offer a convenient choice. Anyhow, here's what I've come up with so far:

    The current QwtPlotRescaler operates on the chart canvas size:

    Qt Code:
    1. //! Adjust the plot axes scales
    2. void QwtPlotRescaler::rescale() const
    3. {
    4. // here we get the size of the plot canvas and use this to adjust the axes
    5. const QSize size = canvas()->contentsRect().size();
    6. rescale( size, size );
    7. }
    To copy to clipboard, switch view to plain text mode 

    Now, within the plot renderer, we cannot use the canvas size, so the first change to implement was to make the

    Qt Code:
    1. // should be public instead of protected
    2. void QwtPlotRescaler::rescale(
    3. const QSize &oldSize, const QSize &newSize ) const
    To copy to clipboard, switch view to plain text mode 

    public. So now it can be called from within the plot renderer.

    Also, the plot renderer needs to know about the rescaler, so an additional (optional) argument is added.

    Qt Code:
    1. // render() function of QwtPlotRenderer get's an optional 4th argument
    2. virtual void render(QwtPlot *,
    3. QPainter *, const QRectF &rect , QwtPlotRescaler *plotRescaler = NULL) const;
    To copy to clipboard, switch view to plain text mode 

    Lastly, we call the plotRescaler after having adjusted the layout:

    Qt Code:
    1. void QwtPlotRenderer::render( QwtPlot *plot,
    2. QPainter *painter, const QRectF &plotRect, QwtPlotRescaler * plotRescaler ) const
    3. {
    4.  
    5. ...
    6. // adjust plot axes based on layoutRect dimensions
    7. if (plotRescaler) {
    8. QSize s = layoutRect.size().toSize();
    9. plotRescaler->rescale(s,s);
    10. }
    11. ...
    To copy to clipboard, switch view to plain text mode 

    this does the trick (almost). Unfortunately, the desired aspect ratio is only kept approximately. So, probably layoutRect() and contentsRect() are not the same here or the scaling within the plot rescaler still does something different. I'll try to track that down...

    @Uwe: do you see a way to get this proportionality feature formally into the QwtPlotRenderer... my variant is certainly a hack and probably not what you would want to have in the official sources, right? :-)

    Bye,
    Andreas


    Added after 10 minutes:


    Update: seems things are not so easy after all - QwtPlotRescaler::updateScales() draws upon the scale div objects in the plot - thus using dimensions of the plot object (that will naturally differ) from the target render rectangle and thus there's a lot of garbage when the original plot dimensions do not match those of the target plot... So I guess implementing the whole scale adjustment stuff anew in the plot render will be necessary :-(

    Does anyone have a better idea?

    -Andreas
    Last edited by ghorwin; 7th May 2019 at 10:17.
    Andreas

  3. #3
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,162
    Thanked 829 Times in 778 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Getting axis rescaler to work while rending chart via QwtPlotRenderer

    Actually the problem is how QwtPlotLayout works: it subtracts title + footer + legend + axes from the given geometry and the rest goes to the canvas.
    That makes sense, as the canvas is the element, that accepts any type of geometry - beside getting too small.

    But if you need a specific aspect ratio it has be done the other way round: you start with the canvas and then attach the other elements accepting, that the plot does not fill the given geometry completely. If you want to try this you could overload QwtPlotLayout::activate, where you calculate the geometries like described.

    Uwe

    PS: what happened to QwtPlotVectorField - would be nice to have this class being complete ?

Similar Threads

  1. qt support yuv directly rending or not
    By waiter in forum Qt Programming
    Replies: 0
    Last Post: 13th January 2013, 04:42
  2. Replies: 1
    Last Post: 27th November 2012, 16:52
  3. Replies: 5
    Last Post: 1st March 2012, 10:13
  4. Replies: 5
    Last Post: 1st March 2011, 14:39
  5. Replies: 1
    Last Post: 2nd May 2010, 18:27

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.