00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kplotobject.h"
00022
00023 #include <QtAlgorithms>
00024 #include <QPainter>
00025
00026 #include <kdebug.h>
00027
00028 #include "kplotpoint.h"
00029 #include "kplotwidget.h"
00030
00031 class KPlotObject::Private
00032 {
00033 public:
00034 Private( KPlotObject * qq )
00035 : q( qq )
00036 {
00037 }
00038
00039 ~Private()
00040 {
00041 qDeleteAll( pList );
00042 }
00043
00044 KPlotObject *q;
00045
00046 QList<KPlotPoint*> pList;
00047 PlotTypes type;
00048 PointStyle pointStyle;
00049 double size;
00050 QPen pen, linePen, barPen, labelPen;
00051 QBrush brush, barBrush;
00052 };
00053
00054 KPlotObject::KPlotObject( const QColor &c, PlotType t, double size, PointStyle ps )
00055 : d( new Private( this ) )
00056 {
00057
00058 setBrush( c );
00059 setBarBrush( c );
00060 setPen( QPen( brush(), 1 ) );
00061 setLinePen( pen() );
00062 setBarPen( pen() );
00063 setLabelPen( pen() );
00064
00065 d->type |= t;
00066 setSize( size );
00067 setPointStyle( ps );
00068 }
00069
00070 KPlotObject::~KPlotObject()
00071 {
00072 delete d;
00073 }
00074
00075 KPlotObject::PlotTypes KPlotObject::plotTypes() const
00076 {
00077 return d->type;
00078 }
00079
00080 void KPlotObject::setShowPoints( bool b )
00081 {
00082 if ( b )
00083 {
00084 d->type |= KPlotObject::Points;
00085 }
00086 else
00087 {
00088 d->type &= ~KPlotObject::Points;
00089 }
00090 }
00091
00092 void KPlotObject::setShowLines( bool b )
00093 {
00094 if ( b )
00095 {
00096 d->type |= KPlotObject::Lines;
00097 }
00098 else
00099 {
00100 d->type &= ~KPlotObject::Lines;
00101 }
00102 }
00103
00104 void KPlotObject::setShowBars( bool b )
00105 {
00106 if ( b )
00107 {
00108 d->type |= KPlotObject::Bars;
00109 }
00110 else
00111 {
00112 d->type &= ~KPlotObject::Bars;
00113 }
00114 }
00115
00116 double KPlotObject::size() const
00117 {
00118 return d->size;
00119 }
00120
00121 void KPlotObject::setSize( double s )
00122 {
00123 d->size = s;
00124 }
00125
00126 KPlotObject::PointStyle KPlotObject::pointStyle() const
00127 {
00128 return d->pointStyle;
00129 }
00130
00131 void KPlotObject::setPointStyle( PointStyle p )
00132 {
00133 d->pointStyle = p;
00134 }
00135
00136 const QPen& KPlotObject::pen() const
00137 {
00138 return d->pen;
00139 }
00140
00141 void KPlotObject::setPen( const QPen &p )
00142 {
00143 d->pen = p;
00144 }
00145
00146 const QPen& KPlotObject::linePen() const
00147 {
00148 return d->linePen;
00149 }
00150
00151 void KPlotObject::setLinePen( const QPen &p )
00152 {
00153 d->linePen = p;
00154 }
00155
00156 const QPen& KPlotObject::barPen() const
00157 {
00158 return d->barPen;
00159 }
00160
00161 void KPlotObject::setBarPen( const QPen &p )
00162 {
00163 d->barPen = p;
00164 }
00165
00166 const QPen& KPlotObject::labelPen() const
00167 {
00168 return d->labelPen;
00169 }
00170
00171 void KPlotObject::setLabelPen( const QPen &p )
00172 {
00173 d->labelPen = p;
00174 }
00175
00176 const QBrush KPlotObject::brush() const
00177 {
00178 return d->brush;
00179 }
00180
00181 void KPlotObject::setBrush( const QBrush &b )
00182 {
00183 d->brush = b;
00184 }
00185
00186 const QBrush KPlotObject::barBrush() const
00187 {
00188 return d->barBrush;
00189 }
00190
00191 void KPlotObject::setBarBrush( const QBrush &b )
00192 {
00193 d->barBrush = b;
00194 }
00195
00196 QList< KPlotPoint* > KPlotObject::points() const
00197 {
00198 return d->pList;
00199 }
00200
00201 void KPlotObject::addPoint( const QPointF &p, const QString &label, double barWidth )
00202 {
00203 addPoint( new KPlotPoint( p.x(), p.y(), label, barWidth ) );
00204 }
00205
00206 void KPlotObject::addPoint( KPlotPoint *p )
00207 {
00208 if ( !p )
00209 return;
00210 d->pList.append( p );
00211 }
00212
00213 void KPlotObject::addPoint( double x, double y, const QString &label, double barWidth )
00214 {
00215 addPoint( new KPlotPoint( x, y, label, barWidth ) );
00216 }
00217
00218 void KPlotObject::removePoint( int index ) {
00219 if ( ( index < 0 ) || ( index >= d->pList.count() ) ) {
00220 kWarning() << "KPlotObject::removePoint(): index " << index << " out of range!";
00221 return;
00222 }
00223
00224 d->pList.removeAt( index );
00225 }
00226
00227 void KPlotObject::clearPoints()
00228 {
00229 qDeleteAll( d->pList );
00230 d->pList.clear();
00231 }
00232
00233 void KPlotObject::draw( QPainter *painter, KPlotWidget *pw ) {
00234
00235
00236
00237 if ( d->type & Bars ) {
00238 painter->setPen( barPen() );
00239 painter->setBrush( barBrush() );
00240
00241 for ( int i=0; i<d->pList.size(); ++i ) {
00242 double w = 0;
00243 if ( d->pList[i]->barWidth() == 0.0 ) {
00244 if ( i<d->pList.size()-1 )
00245 w = d->pList[i+1]->x() - d->pList[i]->x();
00246
00247
00248 } else {
00249 w = d->pList[i]->barWidth();
00250 }
00251
00252 QPointF pp = d->pList[i]->position();
00253 QPointF p1( pp.x() - 0.5*w, 0.0 );
00254 QPointF p2( pp.x() + 0.5*w, pp.y() );
00255 QPointF sp1 = pw->mapToWidget( p1 );
00256 QPointF sp2 = pw->mapToWidget( p2 );
00257
00258 QRectF barRect = QRectF( sp1.x(), sp1.y(), sp2.x()-sp1.x(), sp2.y()-sp1.y() ).normalized();
00259 painter->drawRect( barRect );
00260 pw->maskRect( barRect, 0.25 );
00261 }
00262 }
00263
00264
00265 if ( d->type & Lines ) {
00266 painter->setPen( linePen() );
00267
00268 QPointF Previous = QPointF();
00269
00270 foreach ( KPlotPoint *pp, d->pList ) {
00271
00272 QPointF q = pw->mapToWidget( pp->position() );
00273
00274 if ( ! Previous.isNull() ) {
00275 painter->drawLine( Previous, q );
00276 pw->maskAlongLine( Previous, q );
00277 }
00278
00279 Previous = q;
00280 }
00281 }
00282
00283
00284 if ( d->type & Points ) {
00285
00286 foreach( KPlotPoint *pp, d->pList ) {
00287
00288 QPointF q = pw->mapToWidget( pp->position() );
00289 if ( pw->pixRect().contains( q.toPoint(), false ) ) {
00290 double x1 = q.x() - size();
00291 double y1 = q.y() - size();
00292 QRectF qr = QRectF( x1, y1, 2*size(), 2*size() );
00293
00294
00295 pw->maskRect( qr, 2.0 );
00296
00297 painter->setPen( pen() );
00298 painter->setBrush( brush() );
00299
00300 switch ( pointStyle() ) {
00301 case Circle:
00302 painter->drawEllipse( qr );
00303 break;
00304
00305 case Letter:
00306 painter->drawText( qr, Qt::AlignCenter, pp->label().left(1) );
00307 break;
00308
00309 case Triangle:
00310 {
00311 QPolygonF tri;
00312 tri << QPointF( q.x() - size(), q.y() + size() )
00313 << QPointF( q.x(), q.y() - size() )
00314 << QPointF( q.x() + size(), q.y() + size() );
00315 painter->drawPolygon( tri );
00316 break;
00317 }
00318
00319 case Square:
00320 painter->drawRect( qr );
00321 break;
00322
00323 case Pentagon:
00324 {
00325 QPolygonF pent;
00326 pent << QPointF( q.x(), q.y() - size() )
00327 << QPointF( q.x() + size(), q.y() - 0.309*size() )
00328 << QPointF( q.x() + 0.588*size(), q.y() + size() )
00329 << QPointF( q.x() - 0.588*size(), q.y() + size() )
00330 << QPointF( q.x() - size(), q.y() - 0.309*size() );
00331 painter->drawPolygon( pent );
00332 break;
00333 }
00334
00335 case Hexagon:
00336 {
00337 QPolygonF hex;
00338 hex << QPointF( q.x(), q.y() + size() )
00339 << QPointF( q.x() + size(), q.y() + 0.5*size() )
00340 << QPointF( q.x() + size(), q.y() - 0.5*size() )
00341 << QPointF( q.x(), q.y() - size() )
00342 << QPointF( q.x() - size(), q.y() + 0.5*size() )
00343 << QPointF( q.x() - size(), q.y() - 0.5*size() );
00344 painter->drawPolygon( hex );
00345 break;
00346 }
00347
00348 case Asterisk:
00349 painter->drawLine( q, QPointF( q.x(), q.y() + size() ) );
00350 painter->drawLine( q, QPointF( q.x() + size(), q.y() + 0.5*size() ) );
00351 painter->drawLine( q, QPointF( q.x() + size(), q.y() - 0.5*size() ) );
00352 painter->drawLine( q, QPointF( q.x(), q.y() - size() ) );
00353 painter->drawLine( q, QPointF( q.x() - size(), q.y() + 0.5*size() ) );
00354 painter->drawLine( q, QPointF( q.x() - size(), q.y() - 0.5*size() ) );
00355 break;
00356
00357 case Star:
00358 {
00359 QPolygonF star;
00360 star << QPointF( q.x(), q.y() - size() )
00361 << QPointF( q.x() + 0.2245*size(), q.y() - 0.309*size() )
00362 << QPointF( q.x() + size(), q.y() - 0.309*size() )
00363 << QPointF( q.x() + 0.363*size(), q.y() + 0.118*size() )
00364 << QPointF( q.x() + 0.588*size(), q.y() + size() )
00365 << QPointF( q.x(), q.y() + 0.382*size() )
00366 << QPointF( q.x() - 0.588*size(), q.y() + size() )
00367 << QPointF( q.x() - 0.363*size(), q.y() + 0.118*size() )
00368 << QPointF( q.x() - size(), q.y() - 0.309*size() )
00369 << QPointF( q.x() - 0.2245*size(), q.y() - 0.309*size() );
00370 painter->drawPolygon( star );
00371 break;
00372 }
00373
00374 default:
00375 break;
00376 }
00377 }
00378 }
00379 }
00380
00381
00382 painter->setPen( labelPen() );
00383
00384 foreach ( KPlotPoint *pp, d->pList ) {
00385 QPoint q = pw->mapToWidget( pp->position() ).toPoint();
00386 if ( pw->pixRect().contains(q, false) && ! pp->label().isEmpty() ) {
00387 pw->placeLabel( painter, pp );
00388 }
00389 }
00390
00391 }