From c213a0b4d223200883024627d4eb3e39e360b7b2 Mon Sep 17 00:00:00 2001 From: Andreas Nicolai Date: Sat, 18 Jun 2005 13:46:25 +0000 Subject: [PATCH] - created new class KPlotAxis to store all axis related data - added support for user defined number formats for tick labels svn path=/trunk/KDE/kdeedu/libkdeedu/; revision=426762 --- kdeeduplot/Makefile.am | 2 +- kdeeduplot/kplotaxis.cpp | 32 +++++++ kdeeduplot/kplotaxis.h | 86 +++++++++++++++++ kdeeduplot/kplotwidget.cpp | 185 +++++++++++++++++++------------------ kdeeduplot/kplotwidget.h | 25 ++--- 5 files changed, 229 insertions(+), 101 deletions(-) create mode 100644 kdeeduplot/kplotaxis.cpp create mode 100644 kdeeduplot/kplotaxis.h diff --git a/kdeeduplot/Makefile.am b/kdeeduplot/Makefile.am index 512e836..1586751 100644 --- a/kdeeduplot/Makefile.am +++ b/kdeeduplot/Makefile.am @@ -4,7 +4,7 @@ SUBDIRS = . lib_LTLIBRARIES = libkdeeduplot.la libkdeeduplot_la_SOURCES = \ - kplotobject.cpp kplotwidget.cpp + kplotobject.cpp kplotaxis.cpp kplotwidget.cpp libkdeeduplot_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 3:0:2 libkdeeduplot_la_LIBADD = $(LIB_KDECORE) $(LIB_QT) diff --git a/kdeeduplot/kplotaxis.cpp b/kdeeduplot/kplotaxis.cpp new file mode 100644 index 0000000..0099e0c --- /dev/null +++ b/kdeeduplot/kplotaxis.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + kplotaxis.cpp - An axis for the plot widget + ------------------- + begin : 16 June 2005 + copyright : (C) 2005 by Andreas Nicolai + email : Andreas.Nicolai@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include +#include +#include "kplotaxis.h" + +KPlotAxis::KPlotAxis() : m_visible(true), m_labelFieldWidth(0), m_labelFmt('g'), + m_labelPrec(2) +{ +} + +KPlotAxis::KPlotAxis(const QString& label) : m_visible(true), m_label(label), + m_labelFieldWidth(0), m_labelFmt('g'), m_labelPrec(2) +{ +} + diff --git a/kdeeduplot/kplotaxis.h b/kdeeduplot/kplotaxis.h new file mode 100644 index 0000000..3a82417 --- /dev/null +++ b/kdeeduplot/kplotaxis.h @@ -0,0 +1,86 @@ +/*************************************************************************** + kplotaxis.h - An axis for the plot widget + ------------------- + begin : 16 June 2005 + copyright : (C) 2005 by Andreas Nicolai + email : Andreas.Nicolai@gmx.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KPLOTAXIS_H +#define KPLOTAXIS_H + +#include + +#include + +/**class KPlotAxis + *@short Contains all data for drawing an axis including format specification axis labels. + *@author Andreas Nicolai + *@version 1.0 + */ +class KDE_EXPORT KPlotAxis { +public: + + /**@short Default constructor, creates a default axis. */ + KPlotAxis(); + + /**@short Constructor, constructs a labeled axis. */ + KPlotAxis(const QString& label); + + /**@short Destructor. */ + virtual ~KPlotAxis() {} + + /**@short Returns whether the axis is visible or not. */ + virtual bool isVisible() const { return m_visible; } + + /**@short Sets the "visible" property of the axis. */ + virtual void setVisible(bool visible) { m_visible = visible; } + + /**@short Shows the axis (axis will be shown at next update of plot widget). */ + virtual void show() { m_visible = true; } + + /**@short Hides the axis (axis will be hidden at next update of plot widget). */ + virtual void hide() { m_visible = false; } + + /**@short Sets the axis label. + *@param label A short string describing the data plotted on the axis. + *Set the label to an empty string to omit the axis label. + */ + virtual void setLabel( const QString& label ) { m_label = label; } + + /**@short Returns the axis label. */ + virtual QString label() const { return m_label; } + + /**@short Set the number format for the tick labels, see QString::arg() for + description of arguments. + */ + virtual void setLabelFormat(int fieldWidth, char fmt = 'g', int prec=-1) { + m_labelFieldWidth = fieldWidth; m_labelFmt = fmt; m_labelPrec = prec; } + + /**@short Returns the field width of the tick labels. */ + virtual int labelFieldWidth() const { return m_labelFieldWidth; } + + /**@short Returns the number format of the tick labels. */ + virtual char labelFmt() const { return m_labelFmt; } + + /**@short Returns the number precision of the tick labels. */ + virtual int labelPrec() const { return m_labelPrec; } + +private: + bool m_visible; ///< Property "visible" defines if Axis is drawn or not. + QString m_label; ///< The label of the axis. + int m_labelFieldWidth; ///< Field width for number labels, see QString::arg(). + char m_labelFmt; ///< Number format for number labels, see QString::arg(). + int m_labelPrec; ///< Number precision for number labels, see QString::arg(). +}; + +#endif // KPLOTAXIS_H diff --git a/kdeeduplot/kplotwidget.cpp b/kdeeduplot/kplotwidget.cpp index b800c65..aa46599 100644 --- a/kdeeduplot/kplotwidget.cpp +++ b/kdeeduplot/kplotwidget.cpp @@ -21,14 +21,14 @@ #include #include "kplotwidget.h" +#include "kplotwidget.moc" KPlotWidget::KPlotWidget( double x1, double x2, double y1, double y2, QWidget *parent, const char* name ) : QWidget( parent, name, WNoAutoErase ), dXtick(0.0), dYtick(0.0), nmajX(0), nminX(0), nmajY(0), nminY(0), - ShowAxes( true ), ShowTickMarks( true ), ShowTickLabels( true ), ShowGrid( false ), - XAxisLabel(), YAxisLabel() { - + ShowTickMarks( true ), ShowTickLabels( true ), ShowGrid( false ) + { setBackgroundMode( QWidget::NoBackground ); //set DataRect @@ -261,7 +261,7 @@ void KPlotWidget::drawBox( QPainter *p ) { p->setPen( fgColor() ); p->setBrush( Qt::NoBrush ); - if ( ShowAxes ) p->drawRect( PixRect ); //box outline + if (XAxis.isVisible() || YAxis.isVisible()) p->drawRect( PixRect ); //box outline if ( ShowTickMarks ) { //spacing between minor tickmarks (in data units) @@ -274,105 +274,115 @@ void KPlotWidget::drawBox( QPainter *p ) { 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; - - for ( int ix = 0; ix <= nmajX+1; ix++ ) { - //position of tickmark i (in screen units) - int px = int( PixRect.width() * ( (x0 + ix*dXtick - x() )/dataWidth() ) ); - - if ( px > 0 && px < PixRect.width() ) { - p->drawLine( px, PixRect.height() - 2, px, PixRect.height() - BIGTICKSIZE - 2 ); - p->drawLine( px, 0, px, BIGTICKSIZE ); - } - - //tick label - if ( ShowTickLabels ) { - double lab = x0 + ix*dXtick; - 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 ); + //--- Draw X Axis ---// + if (XAxis.isVisible()) { + // 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; + + for ( int ix = 0; ix <= nmajX+1; ix++ ) { + //position of tickmark i (in screen units) + int px = int( PixRect.width() * ( (x0 + ix*dXtick - x() )/dataWidth() ) ); + if ( px > 0 && px < PixRect.width() ) { - QRect r( px - BIGTICKSIZE, PixRect.height()+BIGTICKSIZE, 2*BIGTICKSIZE, BIGTICKSIZE ); - p->drawText( r, Qt::AlignCenter | Qt::DontClip, str ); + p->drawLine( px, PixRect.height() - 2, px, PixRect.height() - BIGTICKSIZE - 2 ); + p->drawLine( px, 0, px, BIGTICKSIZE ); } - } - - //draw minor ticks - for ( int j=0; j < nminX; j++ ) { - //position of minor tickmark j (in screen units) - int pmin = int( px + PixRect.width()*j*dminX/dataWidth() ); - - if ( pmin > 0 && pmin < PixRect.width() ) { - p->drawLine( pmin, PixRect.height() - 2, pmin, PixRect.height() - SMALLTICKSIZE - 2 ); - p->drawLine( pmin, 0, pmin, SMALLTICKSIZE ); + + //tick label + if ( ShowTickLabels ) { + double lab = x0 + ix*dXtick; + if ( fabs(lab)/dXtick < 0.00001 ) lab = 0.0; //fix occassional roundoff error with "0.0" label + + QString str = QString( "%1" ).arg( lab, XAxis.labelFieldWidth(), XAxis.labelFmt(), XAxis.labelPrec() ); + 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 Y tickmarks---// - double y0 = y() - dmod( y(), dYtick ); //zeropoint; tickmark i is this plus i*dYtick1 (in data units) - if ( y() < 0.0 ) y0 -= dYtick; + + //draw minor ticks + for ( int j=0; j < nminX; j++ ) { + //position of minor tickmark j (in screen units) + int pmin = int( px + PixRect.width()*j*dminX/dataWidth() ); + + if ( pmin > 0 && pmin < PixRect.width() ) { + p->drawLine( pmin, PixRect.height() - 2, pmin, PixRect.height() - SMALLTICKSIZE - 2 ); + p->drawLine( pmin, 0, pmin, SMALLTICKSIZE ); + } + } + } // end draw X tickmarks - for ( int iy = 0; iy <= nmajY+1; iy++ ) { - //position of tickmark i (in screen units) - int py = PixRect.height() - int( PixRect.height() * ( (y0 + iy*dYtick - y())/dataHeight() ) ); - if ( py > 0 && py < PixRect.height() ) { - p->drawLine( 0, py, BIGTICKSIZE, py ); - p->drawLine( PixRect.width()-2, py, PixRect.width()-BIGTICKSIZE-2, py ); + // Draw X Axis Label + if ( ! XAxis.label().isEmpty() ) { + QRect r( 0, PixRect.height() + 2*YPADDING, PixRect.width(), YPADDING ); + p->drawText( r, Qt::AlignCenter, XAxis.label() ); } - //tick label - if ( ShowTickLabels ) { - double lab = y0 + iy*dYtick; - 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 ); + //--- Draw Y Axis ---// + if (YAxis.isVisible()) { + // Draw Y tickmarks + double y0 = y() - dmod( y(), dYtick ); //zeropoint; tickmark i is this plus i*dYtick1 (in data units) + if ( y() < 0.0 ) y0 -= dYtick; + + for ( int iy = 0; iy <= nmajY+1; iy++ ) { + //position of tickmark i (in screen units) + int py = PixRect.height() - int( PixRect.height() * ( (y0 + iy*dYtick - y())/dataHeight() ) ); if ( py > 0 && py < PixRect.height() ) { - QRect r( -2*BIGTICKSIZE, py-SMALLTICKSIZE, 2*BIGTICKSIZE, 2*SMALLTICKSIZE ); - p->drawText( r, Qt::AlignCenter | Qt::DontClip, str ); + p->drawLine( 0, py, BIGTICKSIZE, py ); + p->drawLine( PixRect.width()-2, py, PixRect.width()-BIGTICKSIZE-2, py ); } - } - - //minor ticks - for ( int j=0; j < nminY; j++ ) { - //position of minor tickmark j (in screen units) - int pmin = int( py - PixRect.height()*j*dminY/dataHeight() ); - if ( pmin > 0 && pmin < PixRect.height() ) { - p->drawLine( 0, pmin, SMALLTICKSIZE, pmin ); - p->drawLine( PixRect.width()-2, pmin, PixRect.width()-SMALLTICKSIZE-2, pmin ); + + //tick label + if ( ShowTickLabels ) { + double lab = y0 + iy*dYtick; + if ( fabs(lab)/dYtick < 0.00001 ) lab = 0.0; //fix occassional roundoff error with "0.0" label + + QString str = QString( "%1" ).arg( lab, YAxis.labelFieldWidth(), YAxis.labelFmt(), YAxis.labelPrec() ); + 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 + for ( int j=0; j < nminY; j++ ) { + //position of minor tickmark j (in screen units) + int pmin = int( py - PixRect.height()*j*dminY/dataHeight() ); + if ( pmin > 0 && pmin < PixRect.height() ) { + p->drawLine( 0, pmin, SMALLTICKSIZE, pmin ); + p->drawLine( PixRect.width()-2, pmin, PixRect.width()-SMALLTICKSIZE-2, pmin ); + } } + } // end draw Y tickmarks + + //Draw Y Axis Label. We need to draw the text sideways. + if ( ! YAxis.label().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, YAxis.label() ); //draw the label, now that we are sideways + + p->restore(); //restore translation/rotation state } - } //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 ); + } //end if ( ShowTickMarks ) - 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; + if ( ! YAxis.label().isEmpty() && ShowTickLabels ) return 3*XPADDING; + if ( ! YAxis.label().isEmpty() || ShowTickLabels ) return 2*XPADDING; return XPADDING; } @@ -388,9 +398,8 @@ int KPlotWidget::topPadding() const { int KPlotWidget::bottomPadding() const { if ( BottomPadding >= 0 ) return BottomPadding; - if ( ! XAxisLabel.isEmpty() && ShowTickLabels ) return 3*YPADDING; - if ( ! XAxisLabel.isEmpty() || ShowTickLabels ) return 2*YPADDING; + if ( ! XAxis.label().isEmpty() && ShowTickLabels ) return 3*YPADDING; + if ( ! XAxis.label().isEmpty() || ShowTickLabels ) return 2*YPADDING; return YPADDING; } -#include "kplotwidget.moc" diff --git a/kdeeduplot/kplotwidget.h b/kdeeduplot/kplotwidget.h index 999f138..119e7bd 100644 --- a/kdeeduplot/kplotwidget.h +++ b/kdeeduplot/kplotwidget.h @@ -20,6 +20,7 @@ #include #include "kplotobject.h" +#include "kplotaxis.h" #define BIGTICKSIZE 10 #define SMALLTICKSIZE 4 @@ -32,9 +33,9 @@ class QPixmap; /**@class KPlotWidget *@short Genric data plotting widget. *@author Jason Harris - *@version 1.0 - *Widget for drawing plots. Includes adjustable axes with - *tickmarks and labels, and a list of KPlotObjects to be drawn. + *@version 1.1 + *Widget for drawing plots. Includes adjustable axes (KPlotAxis) with + *tickmarks and labels and a list of KPlotObjects to be drawn. */ class KDE_EXPORT KPlotWidget : public QWidget { @@ -137,7 +138,7 @@ public: *@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; } + virtual void setShowAxes( bool show ) { XAxis.setVisible(show); YAxis.setVisible(show); } /**@short toggle whether tick marks are drawn along the axes. *@param show if true, tick marks will be drawn. */ @@ -155,12 +156,12 @@ public: *@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; } + virtual void setXAxisLabel( QString xlabel ) { XAxis.setLabel(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; } + virtual void setYAxisLabel( QString ylabel ) { YAxis.setLabel(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 @@ -200,10 +201,14 @@ public: */ virtual void setBottomPadding( int pad ) { BottomPadding = pad; } - /**@short revert all four padding values to be automatically determined. - */ + /**@short revert all four padding values to be automatically determined. */ virtual void setDefaultPadding() { LeftPadding = -1; RightPadding = -1; TopPadding = -1; BottomPadding = -1; } + /**@short The X axis. */ + KPlotAxis XAxis; + /**@short The Y axis. */ + KPlotAxis YAxis; + protected: /**@short the paint event handler, executed when update() or repaint() is called. */ @@ -247,13 +252,9 @@ protected: QColor cBackground, cForeground, cGrid; //draw options bool ShowAxes, ShowTickMarks, ShowTickLabels, ShowGrid; - //padding int LeftPadding, RightPadding, TopPadding, BottomPadding; - //Axis Labels - QString XAxisLabel, YAxisLabel; - QPixmap *buffer; }; -- 2.47.3