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