]> Git trees. - libqmvoc.git/commitdiff
Added ability to add axis labels to the plot
authorJason Harris <kstars@30doradus.org>
Sun, 20 Jul 2003 04:52:06 +0000 (04:52 +0000)
committerJason Harris <kstars@30doradus.org>
Sun, 20 Jul 2003 04:52:06 +0000 (04:52 +0000)
(setXAxisLabel(QString)/setYAxisLabel(QString)).
The "padding" space around the plot area is no longer hard-coded.
The amount of padding can be set explicitly with setXXXPadding(int),
where XXX={Left, Right, Top, Bottom}.  If not explicitly set, the code
will automatically choose a good amount of padding, depending on whether
there are Axis Labels and/or Tick Mark Labels present.
Also, the placement of Tick Mark Labels is a bit smarter now; the labels
should be better centered on the corresponding tick.

CCMAIL: kstars-devel@lists.sourceforge.net

svn path=/trunk/kdeedu/libkdeedu/; revision=238085

kdeeduplot/kplotwidget.cpp
kdeeduplot/kplotwidget.h

index ddfb4e7f74e55ff50bdad8e238196e1b2dfc4fc1..602bb82ae10237cfbbd299ef4111e4d54fe94439 100644 (file)
 
 KPlotWidget::KPlotWidget( double x1, double x2, double y1, double y2, QWidget *parent, const char* name )
  : QWidget( parent, name ),
-   dXtick(0.0), dYtick(0.0),
+   dXtick(0.0), dYtick(0.0), XAxisLabel(), YAxisLabel(),
    nmajX(0), nminX(0), nmajY(0), nminY(0),
    ShowAxes( true ), ShowTickMarks( true ), ShowTickLabels( true ), ShowGrid( false ) {
 
        //set DataRect
        setLimits( x1, x2, y1, y2 );
+       setDefaultPadding();
 
-       //Set PixRect (starts at (0,0) because we will translate by XPADDING,YPADDING)
-       PixRect = QRect( 0, 0, width() - XPADDING, height() - YPADDING );
+       //Set PixRect (starts at (0,0) because we will translate by leftPadding(), topPadding() )
+       PixRect = QRect( 0, 0, width() - leftPadding() - rightPadding(),
+                              height() - topPadding() - bottomPadding() );
 
        buffer = new QPixmap();
 
@@ -124,8 +126,8 @@ void KPlotWidget::updateTickmarks() {
 }
 
 void KPlotWidget::resizeEvent( QResizeEvent* /* e */ ) {
-       int newWidth = width() - 2*XPADDING;
-       int newHeight = height() - 2*YPADDING;
+       int newWidth = width() - leftPadding() - rightPadding();
+       int newHeight = height() - topPadding() - bottomPadding();
        PixRect = QRect( 0, 0, newWidth, newHeight );
 
        buffer->resize( width(), height() );
@@ -136,8 +138,7 @@ void KPlotWidget::paintEvent( QPaintEvent* /* e */ ) {
 
        p.begin( buffer );
        p.fillRect( 0, 0, width(), height(), bgColor() );
-
-       p.translate( XPADDING, YPADDING );
+       p.translate( leftPadding(), topPadding() );
 
        drawObjects( &p );
        drawBox( &p );
@@ -148,8 +149,8 @@ void KPlotWidget::paintEvent( QPaintEvent* /* e */ ) {
 
 void KPlotWidget::drawObjects( QPainter *p ) {
        for ( KPlotObject *po = ObjectList.first(); po; po = ObjectList.next() ) {
-               
-               if ( po->points()->count() ) { 
+
+               if ( po->points()->count() ) {
                        //draw the plot object
                        p->setPen( QColor( po->color() ) );
 
@@ -219,14 +220,18 @@ void KPlotWidget::drawBox( QPainter *p ) {
        //First, fill in padding region with bgColor() to mask out-of-bounds plot data
        p->setPen( bgColor() );
        p->setBrush( bgColor() );
+
        //left padding ( don't forget: we have translated by XPADDING, YPADDING )
-       p->drawRect( -XPADDING, -YPADDING, XPADDING, height() );
+       p->drawRect( -leftPadding(), -topPadding(), leftPadding(), height() );
+
        //right padding
-       p->drawRect( PixRect.width(), -YPADDING, XPADDING, height() );
+       p->drawRect( PixRect.width(), -topPadding(), rightPadding(), height() );
+
        //top padding
-       p->drawRect( 0, -YPADDING, PixRect.width(), YPADDING );
+       p->drawRect( 0, -topPadding(), PixRect.width(), topPadding() );
+
        //bottom padding
-       p->drawRect( 0, PixRect.height(), PixRect.width(), YPADDING );
+       p->drawRect( 0, PixRect.height(), PixRect.width(), bottomPadding() );
 
        if ( ShowGrid ) {
                //Grid lines are placed at locations of primary axes' major tickmarks
@@ -257,6 +262,12 @@ void KPlotWidget::drawBox( QPainter *p ) {
                double dminX = dXtick/nminX;
                double dminY = dYtick/nminY;
 
+               //set small font for tick labels
+               QFont f = p->font();
+               int s = f.pointSize();
+               f.setPointSize( s - 2 );
+               p->setFont( f );
+
                //--- Draw X tickmarks---//
                double x0 = x() - dmod( x(), dXtick ); //zeropoint; tickmark i is this plus i*dXtick (in data units)
                if ( x() < 0.0 ) x0 -= dXtick;
@@ -276,8 +287,10 @@ void KPlotWidget::drawBox( QPainter *p ) {
                                if ( fabs(lab)/dXtick < 0.00001 ) lab = 0.0; //fix occassional roundoff error with "0.0" label
 
                                QString str = QString( "%1" ).arg( lab, 0, 'g', 2 );
-                               if ( px > 0 && px < PixRect.width() )
-                                       p->drawText( px - BIGTICKSIZE, PixRect.height() + 2*BIGTICKSIZE, str );
+                               if ( px > 0 && px < PixRect.width() ) {
+                                       QRect r( px - BIGTICKSIZE, PixRect.height()+BIGTICKSIZE, 2*BIGTICKSIZE, BIGTICKSIZE );
+                                       p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
+                               }
                        }
 
                        //draw minor ticks
@@ -310,8 +323,10 @@ void KPlotWidget::drawBox( QPainter *p ) {
                                if ( fabs(lab)/dYtick < 0.00001 ) lab = 0.0; //fix occassional roundoff error with "0.0" label
 
                                QString str = QString( "%1" ).arg( lab, 0, 'g', 2 );
-                               if ( py > 0 && py < PixRect.height() )
-                                       p->drawText( -2*BIGTICKSIZE, py + SMALLTICKSIZE, str );
+                               if ( py > 0 && py < PixRect.height() ) {
+                                       QRect r( -2*BIGTICKSIZE, py-SMALLTICKSIZE, 2*BIGTICKSIZE, 2*SMALLTICKSIZE );
+                                       p->drawText( r, Qt::AlignCenter | Qt::DontClip, str );
+                               }
                        }
 
                        //minor ticks
@@ -325,6 +340,51 @@ void KPlotWidget::drawBox( QPainter *p ) {
                        }
                } //end draw Y tickmarks
        } //end if ( ShowTickMarks )
+
+       //Draw X Axis Label
+       if ( ! XAxisLabel.isEmpty() ) {
+               QRect r( 0, PixRect.height() + 2*YPADDING, PixRect.width(), YPADDING );
+               p->drawText( r, Qt::AlignCenter, XAxisLabel );
+       }
+
+       //Draw Y Axis Label.  We need to draw the text sideways.
+       if ( ! YAxisLabel.isEmpty() ) {
+               //store current painter translation/rotation state
+               p->save();
+
+               //translate coord sys to left corner of axis label rectangle, then rotate 90 degrees.
+               p->translate( -3*XPADDING, PixRect.height() );
+               p->rotate( -90.0 );
+
+               QRect r( 0, 0, PixRect.height(), XPADDING );
+               p->drawText( r, Qt::AlignCenter, YAxisLabel ); //draw the label, now that we are sideways
+
+               p->restore();  //restore translation/rotation state
+       }
+}
+
+int KPlotWidget::leftPadding() const {
+       if ( LeftPadding >= 0 ) return LeftPadding;
+       if ( ! YAxisLabel.isEmpty() && ShowTickLabels ) return 3*XPADDING;
+       if ( ! YAxisLabel.isEmpty() || ShowTickLabels ) return 2*XPADDING;
+       return XPADDING;
+}
+
+int KPlotWidget::rightPadding() const {
+       if ( RightPadding >= 0 ) return RightPadding;
+       return XPADDING;
+}
+
+int KPlotWidget::topPadding() const {
+       if ( TopPadding >= 0 ) return TopPadding;
+       return YPADDING;
+}
+
+int KPlotWidget::bottomPadding() const {
+       if ( BottomPadding >= 0 ) return BottomPadding;
+       if ( ! XAxisLabel.isEmpty() && ShowTickLabels ) return 3*YPADDING;
+       if ( ! XAxisLabel.isEmpty() || ShowTickLabels ) return 2*YPADDING;
+       return YPADDING;
 }
 
 #include "kplotwidget.moc"
index 6c41566aa8297a93df6810e9e1e878515bcc74b2..6ce8e28b19647e4257dcab128f158e04788e38f1 100644 (file)
@@ -23,8 +23,8 @@
 
 #define BIGTICKSIZE 10
 #define SMALLTICKSIZE 4
-#define XPADDING 40
-#define YPADDING 40
+#define XPADDING 20
+#define YPADDING 20
 
 class QColor;
 class QPixmap;
@@ -133,11 +133,77 @@ public:
                */
        virtual void setGridColor( const QColor &gc ) { cGrid = gc; }
 
+       /**@short toggle whether plot axes are drawn.
+               *@param show if true, axes will be drawn.
+               *The axes are just a box outline around the plot.
+               */
        virtual void setShowAxes( bool show ) { ShowAxes = show; }
+       /**@short toggle whether tick marks are drawn along the axes.
+               *@param show if true, tick marks will be drawn.
+               */
        virtual void setShowTickMarks( bool show ) { ShowTickMarks = show; }
+       /**@short toggle whether tick labels are drawn at major tickmarks.
+               *@param show if true, tick labels will be drawn.
+               */
        virtual void setShowTickLabels( bool show ) { ShowTickLabels = show; }
+       /**@short toggle whether grid lines are drawn at major tickmarks.
+               *@param show if true, grid lines will be drawn.
+               */
        virtual void setShowGrid( bool show ) { ShowGrid = show; }
 
+       /**@short set the X-axis label
+               *@param xlabel a short string describing the data plotted on the x-axis.
+               *Set the label to an empty string to omit the axis label.
+               */
+       virtual void setXAxisLabel( QString xlabel ) { XAxisLabel = xlabel; }
+       /**@short set the Y-axis label
+               *@param ylabel a short string describing the data plotted on the y-axis.
+               *Set the label to an empty string to omit the axis label.
+               */
+       virtual void setYAxisLabel( QString ylabel ) { YAxisLabel = ylabel; }
+
+       /**@returns the number of pixels to the left of the plot area.  Padding values
+               *are set to -1 by default; if unchanged, this function will try to guess
+               *a good value, based on whether ticklabels and/or axis labels are to be drawn.
+               */
+       virtual int leftPadding()   const;
+       /**@returns the number of pixels to the right of the plot area.
+               *Padding values are set to -1 by default; if unchanged, this function will try to guess
+               *a good value, based on whether ticklabels and/or axis labels are to be drawn.
+               */
+       virtual int rightPadding()  const;
+       /**@returns the number of pixels above the plot area.
+               *Padding values are set to -1 by default; if unchanged, this function will try to guess
+               *a good value, based on whether ticklabels and/or axis labels are to be drawn.
+               */
+       virtual int topPadding()    const;
+       /**@returns the number of pixels below the plot area.
+               *Padding values are set to -1 by default; if unchanged, this function will try to guess
+               *a good value, based on whether ticklabels and/or axis labels are to be drawn.
+               */
+       virtual int bottomPadding() const;
+
+       /**@short set the number of pixels to the left of the plot area.
+               *Set this to -1 to revert to automatic determination of padding values.
+               */
+       virtual void setLeftPadding( int pad )   { LeftPadding = pad; }
+       /**@short set the number of pixels to the right of the plot area.
+               *Set this to -1 to revert to automatic determination of padding values.
+               */
+       virtual void setRightPadding( int pad )  { RightPadding = pad; }
+       /**@short set the number of pixels above the plot area.
+               *Set this to -1 to revert to automatic determination of padding values.
+               */
+       virtual void setTopPadding( int pad )    { TopPadding = pad; }
+       /**@short set the number of pixels below the plot area.
+               *Set this to -1 to revert to automatic determination of padding values.
+               */
+       virtual void setBottomPadding( int pad ) { BottomPadding = pad; }
+
+       /**@short revert all four padding values to be automatically determined.
+               */
+       virtual void setDefaultPadding() { LeftPadding = -1; RightPadding = -1; TopPadding = -1; BottomPadding = -1; }
+
 protected:
        /**@short the paint event handler, executed when update() or repaint() is called.
                */
@@ -174,7 +240,7 @@ protected:
        QRect PixRect;
        //Limits of the plot area in data units
        DRect DataRect;
-       //List of KPlotObjects 
+       //List of KPlotObjects
        QPtrList<KPlotObject> ObjectList;
 
        //Colors
@@ -182,6 +248,12 @@ protected:
        //draw options
        bool ShowAxes, ShowTickMarks, ShowTickLabels, ShowGrid;
 
+       //padding
+       int LeftPadding, RightPadding, TopPadding, BottomPadding;
+
+       //Axis Labels
+       QString XAxisLabel, YAxisLabel;
+
        QPixmap *buffer;
 };