Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "KDChartStockDiagram.h"
00024 #include "KDChartStockDiagram_p.h"
00025
00026 #include "KDChartPaintContext.h"
00027
00028 using namespace KDChart;
00029
00030 #define d d_func()
00031
00032 StockDiagram::StockDiagram( QWidget *parent, CartesianCoordinatePlane *plane )
00033 : AbstractCartesianDiagram( new Private(), parent, plane )
00034 {
00035 init();
00036 }
00037
00038 StockDiagram::~StockDiagram()
00039 {
00040 }
00041
00045 void StockDiagram::init()
00046 {
00047 d->diagram = this;
00048 d->compressor.setModel( attributesModel() );
00049
00050
00051 d->type = HighLowClose;
00052 d->upTrendCandlestickBrush = QBrush( Qt::white );
00053 d->downTrendCandlestickBrush = QBrush( Qt::black );
00054 d->upTrendCandlestickPen = QPen( Qt::black );
00055 d->downTrendCandlestickPen = QPen( Qt::black );
00056
00057 d->lowHighLinePen = QPen( Qt::black );
00058 setDatasetDimensionInternal( 3 );
00059
00060
00061 setPen( QPen( Qt::black ) );
00062 }
00063
00068 void StockDiagram::setType( Type type )
00069 {
00070 d->type = type;
00071 emit propertiesChanged();
00072 }
00073
00077 StockDiagram::Type StockDiagram::type() const
00078 {
00079 return d->type;
00080 }
00081
00082 void StockDiagram::setStockBarAttributes( const StockBarAttributes &attr )
00083 {
00084 attributesModel()->setModelData(
00085 qVariantFromValue( attr ),
00086 StockBarAttributesRole );
00087 emit propertiesChanged();
00088 }
00089
00090 StockBarAttributes StockDiagram::stockBarAttributes() const
00091 {
00092 return qVariantValue<StockBarAttributes>(
00093 attributesModel()->modelData( StockBarAttributesRole ) );
00094 }
00095
00096 void StockDiagram::setStockBarAttributes( int column, const StockBarAttributes &attr )
00097 {
00098 d->setDatasetAttrs( column, qVariantFromValue( attr ), StockBarAttributesRole );
00099 emit propertiesChanged();
00100 }
00101
00102 StockBarAttributes StockDiagram::stockBarAttributes( int column ) const
00103 {
00104 const QVariant attr( d->datasetAttrs( column, StockBarAttributesRole ) );
00105 if ( attr.isValid() )
00106 return qVariantValue<StockBarAttributes>( attr );
00107 return stockBarAttributes();
00108 }
00109
00115 void StockDiagram::setThreeDBarAttributes( const ThreeDBarAttributes &attr )
00116 {
00117 attributesModel()->setModelData(
00118 qVariantFromValue( attr ),
00119 ThreeDBarAttributesRole );
00120 emit propertiesChanged();
00121 }
00122
00128 ThreeDBarAttributes StockDiagram::threeDBarAttributes() const
00129 {
00130 return qVariantValue<ThreeDBarAttributes>(
00131 attributesModel()->modelData( ThreeDBarAttributesRole ) );
00132 }
00133
00143 void StockDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes &attr )
00144 {
00145 d->setDatasetAttrs( column, qVariantFromValue( attr ), StockBarAttributesRole );
00146 emit propertiesChanged();
00147 }
00148
00158 ThreeDBarAttributes StockDiagram::threeDBarAttributes( int column ) const
00159 {
00160 const QVariant attr( d->datasetAttrs( column, ThreeDBarAttributesRole ) );
00161 if ( attr.isValid() )
00162 return qVariantValue<ThreeDBarAttributes>( attr );
00163 return threeDBarAttributes();
00164 }
00165
00166
00167 void StockDiagram::setLowHighLinePen( const QPen &pen )
00168 {
00169 d->lowHighLinePen = pen;
00170 }
00171
00172 QPen StockDiagram::lowHighLinePen() const
00173 {
00174 return d->lowHighLinePen;
00175 }
00176
00177 void StockDiagram::setLowHighLinePen( int column, const QPen &pen )
00178 {
00179 d->lowHighLinePens[column] = pen;
00180 }
00181
00182 QPen StockDiagram::lowHighLinePen( int column ) const
00183 {
00184 if ( d->lowHighLinePens.contains( column ) )
00185 return d->lowHighLinePens[column];
00186 return d->lowHighLinePen;
00187 }
00188
00189 void StockDiagram::setUpTrendCandlestickBrush( const QBrush &brush )
00190 {
00191 d->upTrendCandlestickBrush = brush;
00192 }
00193
00194 QBrush StockDiagram::upTrendCandlestickBrush() const
00195 {
00196 return d->upTrendCandlestickBrush;
00197 }
00198
00199 void StockDiagram::setDownTrendCandlestickBrush( const QBrush &brush )
00200 {
00201 d->downTrendCandlestickBrush = brush;
00202 }
00203
00204 QBrush StockDiagram::downTrendCandlestickBrush() const
00205 {
00206 return d->downTrendCandlestickBrush;
00207 }
00208
00209 void StockDiagram::setUpTrendCandlestickBrush( int column, const QBrush &brush )
00210 {
00211 d->upTrendCandlestickBrushes[column] = brush;
00212 }
00213
00214 QBrush StockDiagram::upTrendCandlestickBrush( int column ) const
00215 {
00216 if ( d->upTrendCandlestickBrushes.contains( column ) )
00217 return d->upTrendCandlestickBrushes[column];
00218 return d->upTrendCandlestickBrush;
00219 }
00220
00221 void StockDiagram::setDownTrendCandlestickBrush( int column, const QBrush &brush )
00222 {
00223 d->downTrendCandlestickBrushes[column] = brush;
00224 }
00225
00226 QBrush StockDiagram::downTrendCandlestickBrush( int column ) const
00227 {
00228 if ( d->downTrendCandlestickBrushes.contains( column ) )
00229 return d->downTrendCandlestickBrushes[column];
00230 return d->downTrendCandlestickBrush;
00231 }
00232
00233
00234 void StockDiagram::setUpTrendCandlestickPen( const QPen &pen )
00235 {
00236 d->upTrendCandlestickPen = pen;
00237 }
00238
00239 QPen StockDiagram::upTrendCandlestickPen() const
00240 {
00241 return d->upTrendCandlestickPen;
00242 }
00243
00244 void StockDiagram::setDownTrendCandlestickPen( const QPen &pen )
00245 {
00246 d->downTrendCandlestickPen = pen;
00247 }
00248
00249 QPen StockDiagram::downTrendCandlestickPen() const
00250 {
00251 return d->downTrendCandlestickPen;
00252 }
00253
00254 void StockDiagram::setUpTrendCandlestickPen( int column, const QPen &pen )
00255 {
00256 d->upTrendCandlestickPens[column] = pen;
00257 }
00258
00259 QPen StockDiagram::upTrendCandlestickPen( int column ) const
00260 {
00261 if ( d->upTrendCandlestickPens.contains( column ) )
00262 return d->upTrendCandlestickPens[column];
00263 return d->upTrendCandlestickPen;
00264 }
00265
00266 void StockDiagram::setDownTrendCandlestickPen( int column, const QPen &pen )
00267 {
00268 d->downTrendCandlestickPens[column] = pen;
00269 }
00270
00271 QPen StockDiagram::downTrendCandlestickPen( int column ) const
00272 {
00273 if ( d->downTrendCandlestickPens.contains( column ) )
00274 return d->downTrendCandlestickPens[column];
00275 return d->downTrendCandlestickPen;
00276 }
00277
00278 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00279 const
00280 #endif
00281 int StockDiagram::numberOfAbscissaSegments() const { return 1; }
00282
00283 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00284 const
00285 #endif
00286 int StockDiagram::numberOfOrdinateSegments() const { return 1; }
00287
00288 void StockDiagram::paint( PaintContext *context )
00289 {
00290
00291
00292 d->reverseMapper.clear();
00293
00294 PainterSaver painterSaver( context->painter() );
00295 const int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
00296 const int divisor = ( d->type == OpenHighLowClose || d->type == Candlestick ) ? 4 : 3;
00297 const int colCount = attributesModel()->columnCount( attributesModelRootIndex() ) / divisor;
00298 for ( int col = 0; col < colCount; ++col )
00299 {
00300 for ( int row = 0; row < rowCount; row++ ) {
00301 CartesianDiagramDataCompressor::DataPoint low;
00302 CartesianDiagramDataCompressor::DataPoint high;
00303 CartesianDiagramDataCompressor::DataPoint open;
00304 CartesianDiagramDataCompressor::DataPoint close;
00305 CartesianDiagramDataCompressor::DataPoint volume;
00306
00307 if ( d->type == HighLowClose ) {
00308 const CartesianDiagramDataCompressor::CachePosition highPos( row, col * divisor );
00309 const CartesianDiagramDataCompressor::CachePosition lowPos( row, col * divisor + 1 );
00310 const CartesianDiagramDataCompressor::CachePosition closePos( row, col * divisor + 2 );
00311 low = d->compressor.data( lowPos );
00312 high = d->compressor.data( highPos );
00313 close = d->compressor.data( closePos );
00314 } else if ( d->type == OpenHighLowClose || d->type == Candlestick ) {
00315 const CartesianDiagramDataCompressor::CachePosition openPos( row, col * divisor );
00316 const CartesianDiagramDataCompressor::CachePosition highPos( row, col * divisor + 1 );
00317 const CartesianDiagramDataCompressor::CachePosition lowPos( row, col * divisor + 2 );
00318 const CartesianDiagramDataCompressor::CachePosition closePos( row, col * divisor + 3 );
00319 open = d->compressor.data( openPos );
00320 low = d->compressor.data( lowPos );
00321 high = d->compressor.data( highPos );
00322 close = d->compressor.data( closePos );
00323 }
00324
00325
00326 switch( d->type ) {
00327 case HighLowClose:
00328 open.hidden = true;
00329
00330 case OpenHighLowClose:
00331 if ( close.index.isValid() && low.index.isValid() && high.index.isValid() )
00332 d->drawOHLCBar( col, open, high, low, close, context );
00333 break;
00334 case Candlestick:
00335 d->drawCandlestick( col, open, high, low, close, context );
00336 break;
00337 }
00338 }
00339 }
00340 }
00341
00342 void StockDiagram::resize( const QSizeF &size )
00343 {
00344 d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
00345 static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
00346 setDataBoundariesDirty();
00347 }
00348
00349 double StockDiagram::threeDItemDepth( int column ) const
00350 {
00351 Q_UNUSED( column );
00352
00353 return 1.0;
00354 }
00355
00356 double StockDiagram::threeDItemDepth( const QModelIndex &index ) const
00357 {
00358 Q_UNUSED( index );
00359
00360 return 1.0;
00361 }
00362
00363 const QPair<QPointF, QPointF> StockDiagram::calculateDataBoundaries() const
00364 {
00365 const int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
00366 const int colCount = attributesModel()->columnCount( attributesModelRootIndex() );
00367 qreal xMin = 0.0;
00368 qreal xMax = rowCount;
00369 qreal yMin = 0.0;
00370 qreal yMax = 0.0;
00371 for ( int row = 0; row < rowCount; row++ ) {
00372 for ( int col = 0; col < colCount; col++ ) {
00373 const CartesianDiagramDataCompressor::CachePosition pos( row, col );
00374 const CartesianDiagramDataCompressor::DataPoint point = d->compressor.data( pos );
00375 yMax = qMax( yMax, point.value );
00376 yMin = qMin( yMin, point.value );
00377 }
00378 }
00379 return QPair<QPointF, QPointF>( QPointF( xMin, yMin ), QPointF( xMax, yMax ) );
00380 }
00381