Qwt User's Guide 6.3.0
Loading...
Searching...
No Matches
qwt_plot_renderer.cpp
1/******************************************************************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10#include "qwt_plot_renderer.h"
11#include "qwt_plot.h"
12#include "qwt_painter.h"
13#include "qwt_plot_layout.h"
14#include "qwt_abstract_legend.h"
15#include "qwt_scale_widget.h"
16#include "qwt_scale_engine.h"
17#include "qwt_scale_map.h"
18#include "qwt_text.h"
19#include "qwt_text_label.h"
20#include "qwt_math.h"
21
22#include <qpainter.h>
23#include <qpainterpath.h>
24#include <qtransform.h>
25#include <qprinter.h>
26#include <qfiledialog.h>
27#include <qfileinfo.h>
28#include <qimagewriter.h>
29#include <qvariant.h>
30#include <qmargins.h>
31
32#ifndef QWT_NO_SVG
33#ifdef QT_SVG_LIB
34#define QWT_FORMAT_SVG 1
35#endif
36#endif
37
38#ifndef QT_NO_PRINTER
39#define QWT_FORMAT_PDF 1
40#endif
41
42#ifndef QT_NO_PDF
43
44// QPdfWriter::setResolution() has been introduced with
45// Qt 5.3. Guess it is o.k. to stay with QPrinter for older
46// versions.
47
48#if QT_VERSION >= 0x050300
49
50#ifndef QWT_FORMAT_PDF
51#define QWT_FORMAT_PDF 1
52#endif
53
54#define QWT_PDF_WRITER 1
55
56#endif
57#endif
58
59#ifndef QT_NO_PRINTER
60// postscript support has been dropped in Qt5
61#if QT_VERSION < 0x050000
62#define QWT_FORMAT_POSTSCRIPT 1
63#endif
64#endif
65
66#if QWT_FORMAT_SVG
67#include <qsvggenerator.h>
68#endif
69
70#if QWT_PDF_WRITER
71#include <qpdfwriter.h>
72#endif
73
74static qreal qwtScalePenWidth( const QwtPlot* plot )
75{
76 qreal pw = 0.0;
77
78 for ( int axisId = 0; axisId < QwtAxis::AxisPositions; axisId++ )
79 {
80 if ( plot->isAxisVisible( axisId ) )
81 pw = qMax( pw, plot->axisScaleDraw( axisId )->penWidthF() );
82 }
83
84 return pw;
85}
86
87static QColor qwtScalePenColor( const QwtPlot* plot )
88{
89 const QPalette pal = plot->axisWidget( QwtAxis::YLeft )->palette();
90 return pal.color( QPalette::WindowText );
91}
92
93static QPainterPath qwtCanvasClip(
94 const QWidget* canvas, const QRectF& canvasRect )
95{
96 // The clip region is calculated in integers
97 // To avoid too much rounding errors better
98 // calculate it in target device resolution
99
100 int x1 = qwtCeil( canvasRect.left() );
101 int x2 = qwtFloor( canvasRect.right() );
102 int y1 = qwtCeil( canvasRect.top() );
103 int y2 = qwtFloor( canvasRect.bottom() );
104
105 const QRect r( x1, y1, x2 - x1 - 1, y2 - y1 - 1 );
106
107 QPainterPath clipPath;
108
109 ( void ) QMetaObject::invokeMethod(
110 const_cast< QWidget* >( canvas ), "borderPath",
111 Qt::DirectConnection,
112 Q_RETURN_ARG( QPainterPath, clipPath ), Q_ARG( QRect, r ) );
113
114 return clipPath;
115}
116
117static inline QFont qwtResolvedFont( const QWidget* widget )
118{
119 QFont font = widget->font();
120#if QT_VERSION >= 0x060000
121 font.setResolveMask( QFont::AllPropertiesResolved );
122#else
123 font.resolve( QFont::AllPropertiesResolved );
124#endif
125
126 return font;
127}
128
129class QwtPlotRenderer::PrivateData
130{
131 public:
132 PrivateData()
133 : discardFlags( QwtPlotRenderer::DiscardNone )
134 , layoutFlags( QwtPlotRenderer::DefaultLayout )
135 {
136 }
137
140};
141
147 : QObject( parent )
148{
149 m_data = new PrivateData;
150}
151
154{
155 delete m_data;
156}
157
167{
168 if ( on )
169 m_data->discardFlags |= flag;
170 else
171 m_data->discardFlags &= ~flag;
172}
173
180{
181 return m_data->discardFlags & flag;
182}
183
191{
192 m_data->discardFlags = flags;
193}
194
200{
201 return m_data->discardFlags;
202}
203
213{
214 if ( on )
215 m_data->layoutFlags |= flag;
216 else
217 m_data->layoutFlags &= ~flag;
218}
219
226{
227 return m_data->layoutFlags & flag;
228}
229
237{
238 m_data->layoutFlags = flags;
239}
240
246{
247 return m_data->layoutFlags;
248}
249
262 const QString& fileName, const QSizeF& sizeMM, int resolution )
263{
264 renderDocument( plot, fileName,
265 QFileInfo( fileName ).suffix(), sizeMM, resolution );
266}
267
294 const QString& fileName, const QString& format,
295 const QSizeF& sizeMM, int resolution )
296{
297 if ( plot == NULL || sizeMM.isEmpty() || resolution <= 0 )
298 return;
299
300 QString title = plot->title().text();
301 if ( title.isEmpty() )
302 title = "Plot Document";
303
304 const double mmToInch = 1.0 / 25.4;
305 const QSizeF size = sizeMM * mmToInch * resolution;
306
307 const QRectF documentRect( 0.0, 0.0, size.width(), size.height() );
308
309 const QString fmt = format.toLower();
310 if ( fmt == QLatin1String( "pdf" ) )
311 {
312#if QWT_FORMAT_PDF
313
314#if QWT_PDF_WRITER
315 QPdfWriter pdfWriter( fileName );
316 pdfWriter.setPageSize( QPageSize( sizeMM, QPageSize::Millimeter ) );
317 pdfWriter.setTitle( title );
318 pdfWriter.setPageMargins( QMarginsF() );
319 pdfWriter.setResolution( resolution );
320
321 QPainter painter( &pdfWriter );
322 render( plot, &painter, documentRect );
323#else
324 QPrinter printer;
325 printer.setOutputFormat( QPrinter::PdfFormat );
326 printer.setColorMode( QPrinter::Color );
327 printer.setFullPage( true );
328 printer.setPaperSize( sizeMM, QPrinter::Millimeter );
329 printer.setDocName( title );
330 printer.setOutputFileName( fileName );
331 printer.setResolution( resolution );
332
333 QPainter painter( &printer );
334 render( plot, &painter, documentRect );
335#endif
336#endif
337 }
338 else if ( fmt == QLatin1String( "ps" ) )
339 {
340#if QWT_FORMAT_POSTSCRIPT
341 QPrinter printer;
342 printer.setOutputFormat( QPrinter::PostScriptFormat );
343 printer.setColorMode( QPrinter::Color );
344 printer.setFullPage( true );
345 printer.setPaperSize( sizeMM, QPrinter::Millimeter );
346 printer.setDocName( title );
347 printer.setOutputFileName( fileName );
348 printer.setResolution( resolution );
349
350 QPainter painter( &printer );
351 render( plot, &painter, documentRect );
352#endif
353 }
354 else if ( fmt == QLatin1String( "svg" ) )
355 {
356#if QWT_FORMAT_SVG
357 QSvgGenerator generator;
358 generator.setTitle( title );
359 generator.setFileName( fileName );
360 generator.setResolution( resolution );
361 generator.setViewBox( documentRect );
362
363 QPainter painter( &generator );
364 render( plot, &painter, documentRect );
365#endif
366 }
367 else
368 {
369 if ( QImageWriter::supportedImageFormats().indexOf(
370 format.toLatin1() ) >= 0 )
371 {
372 const QRect imageRect = documentRect.toRect();
373 const int dotsPerMeter = qRound( resolution * mmToInch * 1000.0 );
374
375 QImage image( imageRect.size(), QImage::Format_ARGB32 );
376 image.setDotsPerMeterX( dotsPerMeter );
377 image.setDotsPerMeterY( dotsPerMeter );
378 image.fill( QColor( Qt::white ).rgb() );
379
380 QPainter painter( &image );
381 render( plot, &painter, imageRect );
382 painter.end();
383
384 image.save( fileName, format.toLatin1() );
385 }
386 }
387}
388
403 QwtPlot* plot, QPaintDevice& paintDevice ) const
404{
405 int w = paintDevice.width();
406 int h = paintDevice.height();
407
408 QPainter p( &paintDevice );
409 render( plot, &p, QRectF( 0, 0, w, h ) );
410}
411
425#ifndef QT_NO_PRINTER
426
428 QwtPlot* plot, QPrinter& printer ) const
429{
430 int w = printer.width();
431 int h = printer.height();
432
433 QRectF rect( 0, 0, w, h );
434 double aspect = rect.width() / rect.height();
435 if ( ( aspect < 1.0 ) )
436 rect.setHeight( aspect * rect.width() );
437
438 QPainter p( &printer );
439 render( plot, &p, rect );
440}
441
442#endif
443
444#if QWT_FORMAT_SVG
445
458 QwtPlot* plot, QSvgGenerator& generator ) const
459{
460 QRectF rect = generator.viewBoxF();
461 if ( rect.isEmpty() )
462 rect.setRect( 0, 0, generator.width(), generator.height() );
463
464 if ( rect.isEmpty() )
465 rect.setRect( 0, 0, 800, 600 ); // something
466
467 QPainter p( &generator );
468 render( plot, &p, rect );
469}
470
471#endif
472
483 QPainter* painter, const QRectF& plotRect ) const
484{
485 if ( painter == 0 || !painter->isActive() ||
486 !plotRect.isValid() || plot->size().isNull() )
487 {
488 return;
489 }
490
491 if ( !( m_data->discardFlags & DiscardBackground ) )
492 QwtPainter::drawBackgound( painter, plotRect, plot );
493
494 /*
495 The layout engine uses the same methods as they are used
496 by the Qt layout system. Therefore we need to calculate the
497 layout in screen coordinates and paint with a scaled painter.
498 */
499 QTransform transform;
500 transform.scale(
501 double( painter->device()->logicalDpiX() ) / plot->logicalDpiX(),
502 double( painter->device()->logicalDpiY() ) / plot->logicalDpiY() );
503
504 QRectF layoutRect = transform.inverted().mapRect( plotRect );
505
506 if ( !( m_data->discardFlags & DiscardBackground ) )
507 {
508 // subtract the contents margins
509
510 const QMargins m = plot->contentsMargins();
511 layoutRect.adjust( m.left(), m.top(), -m.right(), -m.bottom() );
512 }
513
514 QwtPlotLayout* layout = plot->plotLayout();
515
516 int baseLineDists[QwtAxis::AxisPositions];
517 int canvasMargins[QwtAxis::AxisPositions];
518
519 for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
520 {
521 canvasMargins[axisPos] = layout->canvasMargin( axisPos );
522
523 if ( m_data->layoutFlags & FrameWithScales )
524 {
525 const QwtAxisId axisId( axisPos );
526
527 QwtScaleWidget* scaleWidget = plot->axisWidget( axisId );
528 if ( scaleWidget )
529 {
530 baseLineDists[axisPos] = scaleWidget->margin();
531 scaleWidget->setMargin( 0 );
532 }
533
534 if ( !plot->isAxisVisible( axisId ) )
535 {
536 // When we have a scale the frame is painted on
537 // the position of the backbone - otherwise we
538 // need to introduce a margin around the canvas
539
540 const qreal fw = qwtScalePenWidth( plot );
541
542 switch( axisPos )
543 {
544 case QwtAxis::YLeft:
545 layoutRect.adjust( fw, 0, 0, 0 );
546 break;
547
548 case QwtAxis::YRight:
549 layoutRect.adjust( 0, 0, -fw, 0 );
550 break;
551
552 case QwtAxis::XTop:
553 layoutRect.adjust( 0, fw, 0, 0 );
554 break;
555
556 case QwtAxis::XBottom:
557 layoutRect.adjust( 0, 0, 0, -fw );
558 break;
559
560 default:
561 ;
562 }
563 }
564 }
565 }
566
567 // Calculate the layout for the document.
568
570
571 if ( ( m_data->layoutFlags & FrameWithScales ) ||
572 ( m_data->discardFlags & DiscardCanvasFrame ) )
573 {
574 layoutOptions |= QwtPlotLayout::IgnoreFrames;
575 }
576
577 if ( m_data->discardFlags & DiscardLegend )
578 layoutOptions |= QwtPlotLayout::IgnoreLegend;
579
580 if ( m_data->discardFlags & DiscardTitle )
581 layoutOptions |= QwtPlotLayout::IgnoreTitle;
582
583 if ( m_data->discardFlags & DiscardFooter )
584 layoutOptions |= QwtPlotLayout::IgnoreFooter;
585
586 layout->activate( plot, layoutRect, layoutOptions );
587
588 // canvas
589
590 QwtScaleMap maps[QwtAxis::AxisPositions];
591 buildCanvasMaps( plot, layout->canvasRect(), maps );
592 if ( updateCanvasMargins( plot, layout->canvasRect(), maps ) )
593 {
594 // recalculate maps and layout, when the margins
595 // have been changed
596
597 layout->activate( plot, layoutRect, layoutOptions );
598 buildCanvasMaps( plot, layout->canvasRect(), maps );
599 }
600
601 // now start painting
602
603 painter->save();
604 painter->setWorldTransform( transform, true );
605
606 renderCanvas( plot, painter, layout->canvasRect(), maps );
607
608 if ( !( m_data->discardFlags & DiscardTitle )
609 && ( !plot->titleLabel()->text().isEmpty() ) )
610 {
611 renderTitle( plot, painter, layout->titleRect() );
612 }
613
614 if ( !( m_data->discardFlags & DiscardFooter )
615 && ( !plot->footerLabel()->text().isEmpty() ) )
616 {
617 renderFooter( plot, painter, layout->footerRect() );
618 }
619
620 if ( !( m_data->discardFlags & DiscardLegend )
621 && plot->legend() && !plot->legend()->isEmpty() )
622 {
623 renderLegend( plot, painter, layout->legendRect() );
624 }
625
626 for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
627 {
628 {
629 const QwtAxisId axisId( axisPos );
630
631 QwtScaleWidget* scaleWidget = plot->axisWidget( axisId );
632 if ( scaleWidget )
633 {
634 int baseDist = scaleWidget->margin();
635
636 int startDist, endDist;
637 scaleWidget->getBorderDistHint( startDist, endDist );
638
639 renderScale( plot, painter, axisId, startDist, endDist,
640 baseDist, layout->scaleRect( axisId ) );
641 }
642 }
643 }
644
645 painter->restore();
646
647 // restore all setting to their original attributes.
648 for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
649 {
650 if ( m_data->layoutFlags & FrameWithScales )
651 {
652 const QwtAxisId axisId( axisPos );
653
654 QwtScaleWidget* scaleWidget = plot->axisWidget( axisId );
655 if ( scaleWidget )
656 scaleWidget->setMargin( baseLineDists[axisPos] );
657 }
658
659 layout->setCanvasMargin( canvasMargins[axisPos] );
660 }
661
662 layout->invalidate();
663
664}
665
674 QPainter* painter, const QRectF& titleRect ) const
675{
676 painter->setFont( qwtResolvedFont( plot->titleLabel() ) );
677
678 const QColor color = plot->titleLabel()->palette().color(
679 QPalette::Active, QPalette::Text );
680
681 painter->setPen( color );
682 plot->titleLabel()->text().draw( painter, titleRect );
683}
684
693 QPainter* painter, const QRectF& footerRect ) const
694{
695 painter->setFont( qwtResolvedFont( plot->footerLabel() ) );
696
697 const QColor color = plot->footerLabel()->palette().color(
698 QPalette::Active, QPalette::Text );
699
700 painter->setPen( color );
701 plot->footerLabel()->text().draw( painter, footerRect );
702}
703
712 QPainter* painter, const QRectF& legendRect ) const
713{
714 if ( plot->legend() )
715 {
716 bool fillBackground = !( m_data->discardFlags & DiscardBackground );
717 plot->legend()->renderLegend( painter, legendRect, fillBackground );
718 }
719}
720
733void QwtPlotRenderer::renderScale( const QwtPlot* plot, QPainter* painter,
734 QwtAxisId axisId, int startDist, int endDist, int baseDist,
735 const QRectF& scaleRect ) const
736{
737 if ( !plot->isAxisVisible( axisId ) )
738 return;
739
740 const QwtScaleWidget* scaleWidget = plot->axisWidget( axisId );
741 if ( scaleWidget->isColorBarEnabled()
742 && scaleWidget->colorBarWidth() > 0 )
743 {
744 scaleWidget->drawColorBar( painter, scaleWidget->colorBarRect( scaleRect ) );
745 baseDist += scaleWidget->colorBarWidth() + scaleWidget->spacing();
746 }
747
748 painter->save();
749
751 double x, y, w;
752
753 qreal off = 0.0;
754 if ( m_data->layoutFlags & FrameWithScales )
755 off = qwtScalePenWidth( plot );
756
757 switch ( axisId )
758 {
759 case QwtAxis::YLeft:
760 {
761 x = scaleRect.right() - 1.0 - baseDist - off;
762 y = scaleRect.y() + startDist;
763 w = scaleRect.height() - startDist - endDist;
765 break;
766 }
767 case QwtAxis::YRight:
768 {
769 x = scaleRect.left() + baseDist + off;
770 y = scaleRect.y() + startDist;
771 w = scaleRect.height() - startDist - endDist;
773 break;
774 }
775 case QwtAxis::XTop:
776 {
777 x = scaleRect.left() + startDist;
778 y = scaleRect.bottom() - 1.0 - baseDist - off;
779 w = scaleRect.width() - startDist - endDist;
781 break;
782 }
783 case QwtAxis::XBottom:
784 {
785 x = scaleRect.left() + startDist;
786 y = scaleRect.top() + baseDist + off;
787 w = scaleRect.width() - startDist - endDist;
789 break;
790 }
791 default:
792 return;
793 }
794
795 scaleWidget->drawTitle( painter, align, scaleRect );
796
797 painter->setFont( qwtResolvedFont( scaleWidget ) );
798
799 QwtScaleDraw* sd = const_cast< QwtScaleDraw* >( scaleWidget->scaleDraw() );
800 const QPointF sdPos = sd->pos();
801 const double sdLength = sd->length();
802
803 const bool hasBackbone = sd->hasComponent( QwtAbstractScaleDraw::Backbone );
804
805 if ( m_data->layoutFlags & FrameWithScales )
807
808 sd->move( x, y );
809 sd->setLength( w );
810
811 QPalette palette = scaleWidget->palette();
812 palette.setCurrentColorGroup( QPalette::Active );
813 sd->draw( painter, palette );
814
815 // reset previous values
816 sd->move( sdPos );
817 sd->setLength( sdLength );
819
820 painter->restore();
821}
822
832 QPainter* painter, const QRectF& canvasRect,
833 const QwtScaleMap* maps ) const
834{
835 const QWidget* canvas = plot->canvas();
836
837 QRectF r = canvasRect.adjusted( 0.0, 0.0, -1.0, -1.0 );
838
839 if ( m_data->layoutFlags & FrameWithScales )
840 {
841 painter->save();
842
843 QPen pen;
844 pen.setColor( qwtScalePenColor( plot ) );
845 pen.setWidth( qwtScalePenWidth( plot ) );
846 pen.setJoinStyle( Qt::MiterJoin );
847
848 painter->setPen( pen );
849
850 const qreal pw2 = 0.5 * pen.widthF();
851 r.adjust( -pw2, -pw2, pw2, pw2 );
852
853 if ( !( m_data->discardFlags & DiscardCanvasBackground ) )
854 {
855 const QBrush bgBrush =
856 canvas->palette().brush( plot->backgroundRole() );
857 painter->setBrush( bgBrush );
858 }
859
860 QwtPainter::drawRect( painter, r );
861
862 painter->restore();
863 painter->save();
864
865 painter->setClipRect( canvasRect );
866 plot->drawItems( painter, canvasRect, maps );
867
868 painter->restore();
869 }
870 else if ( canvas->testAttribute( Qt::WA_StyledBackground ) )
871 {
872 QPainterPath clipPath;
873
874 painter->save();
875
876 if ( !( m_data->discardFlags & DiscardCanvasBackground ) )
877 {
878 QwtPainter::drawBackgound( painter, r, canvas );
879 clipPath = qwtCanvasClip( canvas, canvasRect );
880 }
881
882 painter->restore();
883 painter->save();
884
885 if ( clipPath.isEmpty() )
886 painter->setClipRect( canvasRect );
887 else
888 painter->setClipPath( clipPath );
889
890 plot->drawItems( painter, canvasRect, maps );
891
892 painter->restore();
893 }
894 else
895 {
896 QPainterPath clipPath;
897
898 double frameWidth = 0.0;
899
900 if ( !( m_data->discardFlags & DiscardCanvasFrame ) )
901 {
902 const QVariant fw = canvas->property( "frameWidth" );
903 if ( fw.canConvert< double >() )
904 frameWidth = fw.value< double >();
905
906 clipPath = qwtCanvasClip( canvas, canvasRect );
907 }
908
909 QRectF innerRect = canvasRect.adjusted(
910 frameWidth, frameWidth, -frameWidth, -frameWidth );
911
912 painter->save();
913
914 if ( clipPath.isEmpty() )
915 {
916 painter->setClipRect( innerRect );
917 }
918 else
919 {
920 painter->setClipPath( clipPath );
921 }
922
923 if ( !( m_data->discardFlags & DiscardCanvasBackground ) )
924 {
925 QwtPainter::drawBackgound( painter, innerRect, canvas );
926 }
927
928 plot->drawItems( painter, innerRect, maps );
929
930 painter->restore();
931
932 if ( frameWidth > 0 )
933 {
934 painter->save();
935
936 const int frameStyle =
937 canvas->property( "frameShadow" ).toInt() |
938 canvas->property( "frameShape" ).toInt();
939
940 const QVariant borderRadius = canvas->property( "borderRadius" );
941 if ( borderRadius.canConvert< double >()
942 && borderRadius.value< double >() > 0.0 )
943 {
944 const double radius = borderRadius.value< double >();
945
946 QwtPainter::drawRoundedFrame( painter, canvasRect,
947 radius, radius, canvas->palette(), frameWidth, frameStyle );
948 }
949 else
950 {
951 const int midLineWidth = canvas->property( "midLineWidth" ).toInt();
952
953 QwtPainter::drawFrame( painter, canvasRect,
954 canvas->palette(), canvas->foregroundRole(),
955 frameWidth, midLineWidth, frameStyle );
956 }
957 painter->restore();
958 }
959 }
960}
961
969void QwtPlotRenderer::buildCanvasMaps( const QwtPlot* plot,
970 const QRectF& canvasRect, QwtScaleMap maps[] ) const
971{
972 for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
973 {
974 {
975 const QwtAxisId axisId( axisPos );
976
977 QwtScaleMap& scaleMap = maps[axisId];
978
979 scaleMap.setTransformation(
980 plot->axisScaleEngine( axisId )->transformation() );
981
982 const QwtScaleDiv& scaleDiv = plot->axisScaleDiv( axisId );
983 scaleMap.setScaleInterval(
984 scaleDiv.lowerBound(), scaleDiv.upperBound() );
985
986 double from, to;
987 if ( plot->isAxisVisible( axisId ) )
988 {
989 const int sDist = plot->axisWidget( axisId )->startBorderDist();
990 const int eDist = plot->axisWidget( axisId )->endBorderDist();
991 const QRectF scaleRect = plot->plotLayout()->scaleRect( axisId );
992
993 if ( QwtAxis::isXAxis( axisPos ) )
994 {
995 from = scaleRect.left() + sDist;
996 to = scaleRect.right() - eDist;
997 }
998 else
999 {
1000 from = scaleRect.bottom() - eDist;
1001 to = scaleRect.top() + sDist;
1002 }
1003 }
1004 else
1005 {
1006 int margin = 0;
1007 if ( !plot->plotLayout()->alignCanvasToScale( axisPos ) )
1008 margin = plot->plotLayout()->canvasMargin( axisPos );
1009
1010 if ( QwtAxis::isYAxis( axisPos ) )
1011 {
1012 from = canvasRect.bottom() - margin;
1013 to = canvasRect.top() + margin;
1014 }
1015 else
1016 {
1017 from = canvasRect.left() + margin;
1018 to = canvasRect.right() - margin;
1019 }
1020 }
1021 scaleMap.setPaintInterval( from, to );
1022 }
1023 }
1024}
1025
1026bool QwtPlotRenderer::updateCanvasMargins( QwtPlot* plot,
1027 const QRectF& canvasRect, const QwtScaleMap maps[] ) const
1028{
1029 using namespace QwtAxis;
1030
1031 double margins[AxisPositions];
1032 plot->getCanvasMarginsHint( maps, canvasRect,
1033 margins[YLeft], margins[XTop], margins[YRight], margins[XBottom] );
1034
1035 bool marginsChanged = false;
1036 for ( int axisId = 0; axisId < AxisPositions; axisId++ )
1037 {
1038 if ( margins[axisId] >= 0.0 )
1039 {
1040 const int m = qwtCeil( margins[axisId] );
1041 plot->plotLayout()->setCanvasMargin( m, axisId);
1042 marginsChanged = true;
1043 }
1044 }
1045
1046 return marginsChanged;
1047}
1048
1060bool QwtPlotRenderer::exportTo( QwtPlot* plot, const QString& documentName,
1061 const QSizeF& sizeMM, int resolution )
1062{
1063 if ( plot == NULL )
1064 return false;
1065
1066 QString fileName = documentName;
1067
1068 // What about translation
1069
1070#ifndef QT_NO_FILEDIALOG
1071 const QList< QByteArray > imageFormats =
1072 QImageWriter::supportedImageFormats();
1073
1074 QStringList filter;
1075#if QWT_FORMAT_PDF
1076 filter += QString( "PDF " ) + tr( "Documents" ) + " (*.pdf)";
1077#endif
1078#if QWT_FORMAT_SVG
1079 filter += QString( "SVG " ) + tr( "Documents" ) + " (*.svg)";
1080#endif
1081#if QWT_FORMAT_POSTSCRIPT
1082 filter += QString( "Postscript " ) + tr( "Documents" ) + " (*.ps)";
1083#endif
1084
1085 if ( imageFormats.size() > 0 )
1086 {
1087 QString imageFilter( tr( "Images" ) );
1088 imageFilter += " (";
1089 for ( int i = 0; i < imageFormats.size(); i++ )
1090 {
1091 if ( i > 0 )
1092 imageFilter += " ";
1093 imageFilter += "*.";
1094 imageFilter += imageFormats[i];
1095 }
1096 imageFilter += ")";
1097
1098 filter += imageFilter;
1099 }
1100
1101 fileName = QFileDialog::getSaveFileName(
1102 NULL, tr( "Export File Name" ), fileName,
1103 filter.join( ";;" ), NULL, QFileDialog::DontConfirmOverwrite );
1104#endif
1105 if ( fileName.isEmpty() )
1106 return false;
1107
1108 renderDocument( plot, fileName, sizeMM, resolution );
1109
1110 return true;
1111}
1112
1113#include "moc_qwt_plot_renderer.cpp"
virtual void renderLegend(QPainter *painter, const QRectF &rect, bool fillBackground) const =0
virtual bool isEmpty() const =0
@ Backbone
Backbone = the line where the ticks are located.
bool hasComponent(ScaleComponent) const
virtual void draw(QPainter *, const QPalette &) const
Draw the scale.
void enableComponent(ScaleComponent, bool enable=true)
static void drawRoundedFrame(QPainter *, const QRectF &, qreal xRadius, qreal yRadius, const QPalette &, int lineWidth, int frameStyle)
static void drawBackgound(QPainter *, const QRectF &, const QWidget *)
static void drawRect(QPainter *, qreal x, qreal y, qreal w, qreal h)
Wrapper for QPainter::drawRect()
static void drawFrame(QPainter *, const QRectF &rect, const QPalette &palette, QPalette::ColorRole foregroundRole, int lineWidth, int midLineWidth, int frameStyle)
A 2-D plotting widget.
Definition qwt_plot.h:79
virtual void getCanvasMarginsHint(const QwtScaleMap maps[], const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const
Calculate the canvas margins.
Definition qwt_plot.cpp:670
QwtScaleEngine * axisScaleEngine(QwtAxisId)
virtual void drawItems(QPainter *, const QRectF &, const QwtScaleMap maps[QwtAxis::AxisPositions]) const
Definition qwt_plot.cpp:764
QWidget * canvas()
Definition qwt_plot.cpp:463
QwtTextLabel * footerLabel()
Definition qwt_plot.cpp:401
bool isAxisVisible(QwtAxisId) const
QwtPlotLayout * plotLayout()
Definition qwt_plot.cpp:430
QwtAbstractLegend * legend()
Definition qwt_plot.cpp:445
const QwtScaleWidget * axisWidget(QwtAxisId) const
QwtTextLabel * titleLabel()
Definition qwt_plot.cpp:357
const QwtScaleDiv & axisScaleDiv(QwtAxisId) const
Return the scale division of a specified axis.
const QwtScaleDraw * axisScaleDraw(QwtAxisId) const
Return the scale draw of a specified axis.
QwtText title() const
Definition qwt_plot.cpp:351
Layout engine for QwtPlot.
QRectF titleRect() const
void setCanvasMargin(int margin, int axis=-1)
QRectF footerRect() const
int canvasMargin(int axisId) const
QRectF legendRect() const
virtual void invalidate()
bool alignCanvasToScale(int axisId) const
QRectF scaleRect(QwtAxisId) const
QFlags< Option > Options
QRectF canvasRect() const
@ IgnoreTitle
Ignore the title.
@ IgnoreFooter
Ignore the footer.
@ IgnoreFrames
Ignore all frames.
@ IgnoreLegend
Ignore the legend.
virtual void activate(const QwtPlot *, const QRectF &plotRect, Options options=Options())
Recalculate the geometry of all components.
Renderer for exporting a plot to a document, a printer or anything else, that is supported by QPainte...
void renderTo(QwtPlot *, QPrinter &) const
Render the plot to a QPrinter.
LayoutFlag
Layout flags.
@ DefaultLayout
Use the default layout as on screen.
virtual void renderCanvas(const QwtPlot *, QPainter *, const QRectF &canvasRect, const QwtScaleMap *maps) const
virtual void renderFooter(const QwtPlot *, QPainter *, const QRectF &footerRect) const
void setDiscardFlag(DiscardFlag flag, bool on=true)
DiscardFlag
Discard flags.
@ DiscardFooter
Don't render the footer of the plot.
@ DiscardTitle
Don't render the title of the plot.
@ DiscardBackground
Don't render the background of the plot.
@ DiscardCanvasBackground
Don't render the background of the canvas.
@ DiscardLegend
Don't render the legend of the plot.
@ DiscardNone
Render all components of the plot.
virtual void renderLegend(const QwtPlot *, QPainter *, const QRectF &legendRect) const
void setLayoutFlags(LayoutFlags flags)
virtual ~QwtPlotRenderer()
Destructor.
virtual void renderScale(const QwtPlot *, QPainter *, QwtAxisId, int startDist, int endDist, int baseDist, const QRectF &scaleRect) const
Paint a scale into a given rectangle. Paint the scale into a given rectangle.
virtual void renderTitle(const QwtPlot *, QPainter *, const QRectF &titleRect) const
bool testLayoutFlag(LayoutFlag flag) const
void renderDocument(QwtPlot *, const QString &fileName, const QSizeF &sizeMM, int resolution=85)
QwtPlotRenderer(QObject *=NULL)
QFlags< LayoutFlag > LayoutFlags
void setLayoutFlag(LayoutFlag flag, bool on=true)
QFlags< DiscardFlag > DiscardFlags
DiscardFlags discardFlags() const
bool exportTo(QwtPlot *, const QString &documentName, const QSizeF &sizeMM=QSizeF(300, 200), int resolution=85)
Execute a file dialog and render the plot to the selected file.
void setDiscardFlags(DiscardFlags flags)
bool testDiscardFlag(DiscardFlag flag) const
virtual void render(QwtPlot *, QPainter *, const QRectF &plotRect) const
LayoutFlags layoutFlags() const
A class representing a scale division.
double lowerBound() const
double upperBound() const
A class for drawing scales.
void setLength(double length)
void move(double x, double y)
double length() const
QPointF pos() const
@ BottomScale
The scale is below.
@ TopScale
The scale is above.
@ RightScale
The scale is right.
@ LeftScale
The scale is left.
QwtTransform * transformation() const
A scale map.
void setPaintInterval(double p1, double p2)
Specify the borders of the paint device interval.
void setScaleInterval(double s1, double s2)
Specify the borders of the scale interval.
void setTransformation(QwtTransform *)
A Widget which contains a scale.
int startBorderDist() const
void drawColorBar(QPainter *, const QRectF &) const
const QwtScaleDraw * scaleDraw() const
void setMargin(int)
Specify the margin to the colorBar/base line.
bool isColorBarEnabled() const
void drawTitle(QPainter *, QwtScaleDraw::Alignment, const QRectF &rect) const
int endBorderDist() const
void getBorderDistHint(int &start, int &end) const
Calculate a hint for the border distances.
QRectF colorBarRect(const QRectF &) const
int colorBarWidth() const
bool isEmpty() const
Definition qwt_text.cpp:739
void draw(QPainter *painter, const QRectF &rect) const
Definition qwt_text.cpp:615
QString text() const
Definition qwt_text.cpp:289
const QwtText & text() const
Return the text.
bool isYAxis(int axisPos)
Definition qwt_axis.h:57
@ YRight
Y axis right of the canvas.
Definition qwt_axis.h:27
@ XTop
X axis above the canvas.
Definition qwt_axis.h:33
@ XBottom
X axis below the canvas.
Definition qwt_axis.h:30
@ YLeft
Y axis left of the canvas.
Definition qwt_axis.h:24
bool isXAxis(int axisPos)
Definition qwt_axis.h:51