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
00059 setPen( QPen( Qt::black ) );
00060 }
00061
00066 void StockDiagram::setType( Type type )
00067 {
00068 d->type = type;
00069 emit propertiesChanged();
00070 }
00071
00075 StockDiagram::Type StockDiagram::type() const
00076 {
00077 return d->type;
00078 }
00079
00080 void StockDiagram::setStockBarAttributes( const StockBarAttributes &attr )
00081 {
00082 attributesModel()->setModelData(
00083 qVariantFromValue( attr ),
00084 StockBarAttributesRole );
00085 emit propertiesChanged();
00086 }
00087
00088 StockBarAttributes StockDiagram::stockBarAttributes() const
00089 {
00090 return qVariantValue<StockBarAttributes>(
00091 attributesModel()->modelData( StockBarAttributesRole ) );
00092 }
00093
00094 void StockDiagram::setStockBarAttributes( int column, const StockBarAttributes &attr )
00095 {
00096 d->setDatasetAttrs( column, qVariantFromValue( attr ), StockBarAttributesRole );
00097 emit propertiesChanged();
00098 }
00099
00100 StockBarAttributes StockDiagram::stockBarAttributes( int column ) const
00101 {
00102 const QVariant attr( d->datasetAttrs( column, StockBarAttributesRole ) );
00103 if ( attr.isValid() )
00104 return qVariantValue<StockBarAttributes>( attr );
00105 return stockBarAttributes();
00106 }
00107
00113 void StockDiagram::setThreeDBarAttributes( const ThreeDBarAttributes &attr )
00114 {
00115 attributesModel()->setModelData(
00116 qVariantFromValue( attr ),
00117 ThreeDBarAttributesRole );
00118 emit propertiesChanged();
00119 }
00120
00126 ThreeDBarAttributes StockDiagram::threeDBarAttributes() const
00127 {
00128 return qVariantValue<ThreeDBarAttributes>(
00129 attributesModel()->modelData( ThreeDBarAttributesRole ) );
00130 }
00131
00141 void StockDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes &attr )
00142 {
00143 d->setDatasetAttrs( column, qVariantFromValue( attr ), StockBarAttributesRole );
00144 emit propertiesChanged();
00145 }
00146
00156 ThreeDBarAttributes StockDiagram::threeDBarAttributes( int column ) const
00157 {
00158 const QVariant attr( d->datasetAttrs( column, ThreeDBarAttributesRole ) );
00159 if ( attr.isValid() )
00160 return qVariantValue<ThreeDBarAttributes>( attr );
00161 return threeDBarAttributes();
00162 }
00163
00164
00165 void StockDiagram::setLowHighLinePen( const QPen &pen )
00166 {
00167 d->lowHighLinePen = pen;
00168 }
00169
00170 QPen StockDiagram::lowHighLinePen() const
00171 {
00172 return d->lowHighLinePen;
00173 }
00174
00175 void StockDiagram::setLowHighLinePen( int column, const QPen &pen )
00176 {
00177 d->lowHighLinePens[column] = pen;
00178 }
00179
00180 QPen StockDiagram::lowHighLinePen( int column ) const
00181 {
00182 if ( d->lowHighLinePens.contains( column ) )
00183 return d->lowHighLinePens[column];
00184 return d->lowHighLinePen;
00185 }
00186
00187 void StockDiagram::setUpTrendCandlestickBrush( const QBrush &brush )
00188 {
00189 d->upTrendCandlestickBrush = brush;
00190 }
00191
00192 QBrush StockDiagram::upTrendCandlestickBrush() const
00193 {
00194 return d->upTrendCandlestickBrush;
00195 }
00196
00197 void StockDiagram::setDownTrendCandlestickBrush( const QBrush &brush )
00198 {
00199 d->downTrendCandlestickBrush = brush;
00200 }
00201
00202 QBrush StockDiagram::downTrendCandlestickBrush() const
00203 {
00204 return d->downTrendCandlestickBrush;
00205 }
00206
00207 void StockDiagram::setUpTrendCandlestickBrush( int column, const QBrush &brush )
00208 {
00209 d->upTrendCandlestickBrushes[column] = brush;
00210 }
00211
00212 QBrush StockDiagram::upTrendCandlestickBrush( int column ) const
00213 {
00214 if ( d->upTrendCandlestickBrushes.contains( column ) )
00215 return d->upTrendCandlestickBrushes[column];
00216 return d->upTrendCandlestickBrush;
00217 }
00218
00219 void StockDiagram::setDownTrendCandlestickBrush( int column, const QBrush &brush )
00220 {
00221 d->downTrendCandlestickBrushes[column] = brush;
00222 }
00223
00224 QBrush StockDiagram::downTrendCandlestickBrush( int column ) const
00225 {
00226 if ( d->downTrendCandlestickBrushes.contains( column ) )
00227 return d->downTrendCandlestickBrushes[column];
00228 return d->downTrendCandlestickBrush;
00229 }
00230
00231
00232 void StockDiagram::setUpTrendCandlestickPen( const QPen &pen )
00233 {
00234 d->upTrendCandlestickPen = pen;
00235 }
00236
00237 QPen StockDiagram::upTrendCandlestickPen() const
00238 {
00239 return d->upTrendCandlestickPen;
00240 }
00241
00242 void StockDiagram::setDownTrendCandlestickPen( const QPen &pen )
00243 {
00244 d->downTrendCandlestickPen = pen;
00245 }
00246
00247 QPen StockDiagram::downTrendCandlestickPen() const
00248 {
00249 return d->downTrendCandlestickPen;
00250 }
00251
00252 void StockDiagram::setUpTrendCandlestickPen( int column, const QPen &pen )
00253 {
00254 d->upTrendCandlestickPens[column] = pen;
00255 }
00256
00257 QPen StockDiagram::upTrendCandlestickPen( int column ) const
00258 {
00259 if ( d->upTrendCandlestickPens.contains( column ) )
00260 return d->upTrendCandlestickPens[column];
00261 return d->upTrendCandlestickPen;
00262 }
00263
00264 void StockDiagram::setDownTrendCandlestickPen( int column, const QPen &pen )
00265 {
00266 d->downTrendCandlestickPens[column] = pen;
00267 }
00268
00269 QPen StockDiagram::downTrendCandlestickPen( int column ) const
00270 {
00271 if ( d->downTrendCandlestickPens.contains( column ) )
00272 return d->downTrendCandlestickPens[column];
00273 return d->downTrendCandlestickPen;
00274 }
00275
00276 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00277 const
00278 #endif
00279 int StockDiagram::numberOfAbscissaSegments() const { return 1; }
00280
00281 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00282 const
00283 #endif
00284 int StockDiagram::numberOfOrdinateSegments() const { return 1; }
00285
00286 void StockDiagram::paint( PaintContext *context )
00287 {
00288
00289
00290 d->reverseMapper.clear();
00291
00292 PainterSaver painterSaver( context->painter() );
00293 int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
00294 for ( int row = 0; row < rowCount; row++ ) {
00295 CartesianDiagramDataCompressor::DataPoint low;
00296 CartesianDiagramDataCompressor::DataPoint high;
00297 CartesianDiagramDataCompressor::DataPoint open;
00298 CartesianDiagramDataCompressor::DataPoint close;
00299 CartesianDiagramDataCompressor::DataPoint volume;
00300
00301 if ( d->type == HighLowClose ) {
00302 const CartesianDiagramDataCompressor::CachePosition highPos( row, 0 );
00303 const CartesianDiagramDataCompressor::CachePosition lowPos( row, 1 );
00304 const CartesianDiagramDataCompressor::CachePosition closePos( row, 2 );
00305 low = d->compressor.data( lowPos );
00306 high = d->compressor.data( highPos );
00307 close = d->compressor.data( closePos );
00308 } else if ( d->type == OpenHighLowClose || d->type == Candlestick ) {
00309 const CartesianDiagramDataCompressor::CachePosition openPos( row, 0 );
00310 const CartesianDiagramDataCompressor::CachePosition highPos( row, 1 );
00311 const CartesianDiagramDataCompressor::CachePosition lowPos( row, 2 );
00312 const CartesianDiagramDataCompressor::CachePosition closePos( row, 3 );
00313 open = d->compressor.data( openPos );
00314 low = d->compressor.data( lowPos );
00315 high = d->compressor.data( highPos );
00316 close = d->compressor.data( closePos );
00317 }
00318
00319 switch( d->type ) {
00320 case HighLowClose:
00321 open.hidden = true;
00322
00323 case OpenHighLowClose:
00324 d->drawOHLCBar( open, high, low, close, context );
00325 break;
00326 case Candlestick:
00327 d->drawCandlestick( open, high, low, close, context );
00328 break;
00329 }
00330 }
00331 }
00332
00333 void StockDiagram::resize( const QSizeF &size )
00334 {
00335 d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
00336 static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
00337 setDataBoundariesDirty();
00338 }
00339
00340 double StockDiagram::threeDItemDepth( int column ) const
00341 {
00342 Q_UNUSED( column );
00343
00344 return 1.0;
00345 }
00346
00347 double StockDiagram::threeDItemDepth( const QModelIndex &index ) const
00348 {
00349 Q_UNUSED( index );
00350
00351 return 1.0;
00352 }
00353
00354 const QPair<QPointF, QPointF> StockDiagram::calculateDataBoundaries() const
00355 {
00356 const int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
00357 const int colCount = attributesModel()->columnCount( attributesModelRootIndex() );
00358 qreal xMin = 0.0;
00359 qreal xMax = rowCount;
00360 qreal yMin = 0.0;
00361 qreal yMax = 0.0;
00362 for ( int row = 0; row < rowCount; row++ ) {
00363 for ( int col = 0; col < colCount; col++ ) {
00364 const CartesianDiagramDataCompressor::CachePosition pos( row, col );
00365 const CartesianDiagramDataCompressor::DataPoint point = d->compressor.data( pos );
00366 yMax = qMax( yMax, point.value );
00367 yMin = qMin( yMin, point.value );
00368 }
00369 }
00370 return QPair<QPointF, QPointF>( QPointF( xMin, yMin ), QPointF( xMax, yMax ) );
00371 }
00372