KD Chart 2  [rev.2.5]
KDChartStockDiagram.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (C) 2001-2012 Klaralvdalens Datakonsult AB.  All rights reserved.
00003 **
00004 ** This file is part of the KD Chart library.
00005 **
00006 ** Licensees holding valid commercial KD Chart licenses may use this file in
00007 ** accordance with the KD Chart Commercial License Agreement provided with
00008 ** the Software.
00009 **
00010 **
00011 ** This file may be distributed and/or modified under the terms of the
00012 ** GNU General Public License version 2 and version 3 as published by the
00013 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
00014 **
00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 **
00018 ** Contact info@kdab.com if any conditions of this licensing are not
00019 ** clear to you.
00020 **
00021 **********************************************************************/
00022 
00023 #include "KDChartStockDiagram.h"
00024 #include "KDChartStockDiagram_p.h"
00025 
00026 #include "KDChartPaintContext.h"
00027 #include "KDChartPainterSaver_p.h"
00028 
00029 using namespace KDChart;
00030 
00031 #define d d_func()
00032 
00033 StockDiagram::StockDiagram( QWidget *parent, CartesianCoordinatePlane *plane )
00034     : AbstractCartesianDiagram( new Private(), parent, plane )
00035 {
00036     init();
00037 }
00038 
00039 StockDiagram::~StockDiagram()
00040 {
00041 }
00042 
00046 void StockDiagram::init()
00047 {
00048     d->diagram = this;
00049     d->compressor.setModel( attributesModel() );
00050 
00051     // Set properties to defaults
00052     d->type = HighLowClose;
00053     d->upTrendCandlestickBrush = QBrush( Qt::white );
00054     d->downTrendCandlestickBrush = QBrush( Qt::black );
00055     d->upTrendCandlestickPen = QPen( Qt::black );
00056     d->downTrendCandlestickPen = QPen( Qt::black );
00057 
00058     d->lowHighLinePen = QPen( Qt::black );
00059     setDatasetDimensionInternal( 3 );
00060     //setDatasetDimension( 3 );
00061 
00062     setPen( QPen( Qt::black ) );
00063 }
00064 
00069 void StockDiagram::setType( Type type )
00070 {
00071     d->type = type;
00072     emit propertiesChanged();
00073 }
00074 
00078 StockDiagram::Type StockDiagram::type() const
00079 {
00080    return d->type;
00081 }
00082 
00083 void StockDiagram::setStockBarAttributes( const StockBarAttributes &attr )
00084 {
00085     attributesModel()->setModelData(
00086             qVariantFromValue( attr ),
00087             StockBarAttributesRole );
00088     emit propertiesChanged();
00089 }
00090 
00091 StockBarAttributes StockDiagram::stockBarAttributes() const
00092 {
00093     return qVariantValue<StockBarAttributes>(
00094         attributesModel()->modelData( StockBarAttributesRole ) );
00095 }
00096 
00097 void StockDiagram::setStockBarAttributes( int column, const StockBarAttributes &attr )
00098 {
00099     d->setDatasetAttrs( column, qVariantFromValue( attr ), StockBarAttributesRole );
00100     emit propertiesChanged();
00101 }
00102 
00103 StockBarAttributes StockDiagram::stockBarAttributes( int column ) const
00104 {
00105     const QVariant attr( d->datasetAttrs( column, StockBarAttributesRole ) );
00106     if ( attr.isValid() )
00107         return qVariantValue<StockBarAttributes>( attr );
00108     return stockBarAttributes();
00109 }
00110 
00116 void StockDiagram::setThreeDBarAttributes( const ThreeDBarAttributes &attr )
00117 {
00118     attributesModel()->setModelData(
00119             qVariantFromValue( attr ),
00120             ThreeDBarAttributesRole );
00121     emit propertiesChanged();
00122 }
00123 
00129 ThreeDBarAttributes StockDiagram::threeDBarAttributes() const
00130 {
00131         return qVariantValue<ThreeDBarAttributes>(
00132                         attributesModel()->modelData( ThreeDBarAttributesRole ) );
00133 }
00134 
00144 void StockDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes &attr )
00145 {
00146     d->setDatasetAttrs( column, qVariantFromValue( attr ), StockBarAttributesRole );
00147     emit propertiesChanged();
00148 }
00149 
00159 ThreeDBarAttributes StockDiagram::threeDBarAttributes( int column ) const
00160 {
00161     const QVariant attr( d->datasetAttrs( column, ThreeDBarAttributesRole ) );
00162     if ( attr.isValid() )
00163         return qVariantValue<ThreeDBarAttributes>( attr );
00164     return threeDBarAttributes();
00165 }
00166 
00167 
00168 void StockDiagram::setLowHighLinePen( const QPen &pen )
00169 {
00170     d->lowHighLinePen = pen;
00171 }
00172 
00173 QPen StockDiagram::lowHighLinePen() const
00174 {
00175     return d->lowHighLinePen;
00176 }
00177 
00178 void StockDiagram::setLowHighLinePen( int column, const QPen &pen )
00179 {
00180     d->lowHighLinePens[column] = pen;
00181 }
00182 
00183 QPen StockDiagram::lowHighLinePen( int column ) const
00184 {
00185     if ( d->lowHighLinePens.contains( column ) )
00186         return d->lowHighLinePens[column];
00187     return d->lowHighLinePen;
00188 }
00189 
00190 void StockDiagram::setUpTrendCandlestickBrush( const QBrush &brush )
00191 {
00192     d->upTrendCandlestickBrush = brush;
00193 }
00194 
00195 QBrush StockDiagram::upTrendCandlestickBrush() const
00196 {
00197     return d->upTrendCandlestickBrush;
00198 }
00199 
00200 void StockDiagram::setDownTrendCandlestickBrush( const QBrush &brush )
00201 {
00202     d->downTrendCandlestickBrush = brush;
00203 }
00204 
00205 QBrush StockDiagram::downTrendCandlestickBrush() const
00206 {
00207     return d->downTrendCandlestickBrush;
00208 }
00209 
00210 void StockDiagram::setUpTrendCandlestickBrush( int column, const QBrush &brush )
00211 {
00212     d->upTrendCandlestickBrushes[column] = brush;
00213 }
00214 
00215 QBrush StockDiagram::upTrendCandlestickBrush( int column ) const
00216 {
00217     if ( d->upTrendCandlestickBrushes.contains( column ) )
00218         return d->upTrendCandlestickBrushes[column];
00219     return d->upTrendCandlestickBrush;
00220 }
00221 
00222 void StockDiagram::setDownTrendCandlestickBrush( int column, const QBrush &brush )
00223 {
00224     d->downTrendCandlestickBrushes[column] = brush;
00225 }
00226 
00227 QBrush StockDiagram::downTrendCandlestickBrush( int column ) const
00228 {
00229     if ( d->downTrendCandlestickBrushes.contains( column ) )
00230         return d->downTrendCandlestickBrushes[column];
00231     return d->downTrendCandlestickBrush;
00232 }
00233 
00234 
00235 void StockDiagram::setUpTrendCandlestickPen( const QPen &pen )
00236 {
00237     d->upTrendCandlestickPen = pen;
00238 }
00239 
00240 QPen StockDiagram::upTrendCandlestickPen() const
00241 {
00242     return d->upTrendCandlestickPen;
00243 }
00244 
00245 void StockDiagram::setDownTrendCandlestickPen( const QPen &pen )
00246 {
00247     d->downTrendCandlestickPen = pen;
00248 }
00249 
00250 QPen StockDiagram::downTrendCandlestickPen() const
00251 {
00252     return d->downTrendCandlestickPen;
00253 }
00254 
00255 void StockDiagram::setUpTrendCandlestickPen( int column, const QPen &pen )
00256 {
00257     d->upTrendCandlestickPens[column] = pen;
00258 }
00259 
00260 QPen StockDiagram::upTrendCandlestickPen( int column ) const
00261 {
00262     if ( d->upTrendCandlestickPens.contains( column ) )
00263         return d->upTrendCandlestickPens[column];
00264     return d->upTrendCandlestickPen;
00265 }
00266 
00267 void StockDiagram::setDownTrendCandlestickPen( int column, const QPen &pen )
00268 {
00269     d->downTrendCandlestickPens[column] = pen;
00270 }
00271 
00272 QPen StockDiagram::downTrendCandlestickPen( int column ) const
00273 {
00274     if ( d->downTrendCandlestickPens.contains( column ) )
00275         return d->downTrendCandlestickPens[column];
00276     return d->downTrendCandlestickPen;
00277 }
00278 
00279 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00280 const
00281 #endif
00282 int StockDiagram::numberOfAbscissaSegments() const { return 1; }
00283 
00284 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00285 const
00286 #endif
00287 int StockDiagram::numberOfOrdinateSegments() const { return 1; }
00288 
00289 void StockDiagram::paint( PaintContext *context )
00290 {
00291     // Clear old reverse mapping data and create new
00292     // reverse mapping scene
00293     d->reverseMapper.clear();
00294 
00295     PainterSaver painterSaver( context->painter() );
00296     const int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
00297     const int divisor = ( d->type == OpenHighLowClose || d->type == Candlestick ) ? 4 : 3;
00298     const int colCount = attributesModel()->columnCount( attributesModelRootIndex() ) / divisor;
00299     for ( int col = 0; col < colCount; ++col )
00300     {
00301         for ( int row = 0; row < rowCount; row++ ) {
00302             CartesianDiagramDataCompressor::DataPoint low;
00303             CartesianDiagramDataCompressor::DataPoint high;
00304             CartesianDiagramDataCompressor::DataPoint open;
00305             CartesianDiagramDataCompressor::DataPoint close;
00306             CartesianDiagramDataCompressor::DataPoint volume;
00307 
00308             if ( d->type == HighLowClose ) {
00309                 const CartesianDiagramDataCompressor::CachePosition highPos( row, col * divisor );
00310                 const CartesianDiagramDataCompressor::CachePosition lowPos( row, col * divisor + 1 );
00311                 const CartesianDiagramDataCompressor::CachePosition closePos( row, col * divisor + 2 );
00312                 low = d->compressor.data( lowPos );
00313                 high = d->compressor.data( highPos );
00314                 close = d->compressor.data( closePos );
00315             } else if ( d->type == OpenHighLowClose || d->type == Candlestick ) {
00316                 const CartesianDiagramDataCompressor::CachePosition openPos( row, col * divisor );
00317                 const CartesianDiagramDataCompressor::CachePosition highPos( row, col * divisor + 1 );
00318                 const CartesianDiagramDataCompressor::CachePosition lowPos( row, col * divisor + 2 );
00319                 const CartesianDiagramDataCompressor::CachePosition closePos( row, col * divisor + 3 );
00320                 open = d->compressor.data( openPos );
00321                 low = d->compressor.data( lowPos );
00322                 high = d->compressor.data( highPos );
00323                 close = d->compressor.data( closePos );
00324             }
00325 
00326 
00327             switch( d->type ) {
00328             case HighLowClose:
00329                 open.hidden = true;
00330                 // Fall-through intended!
00331             case OpenHighLowClose:
00332                 if ( close.index.isValid() && low.index.isValid() && high.index.isValid() )
00333                 d->drawOHLCBar( col, open, high, low, close, context );
00334                 break;
00335             case Candlestick:
00336                 d->drawCandlestick( col, open, high, low, close, context );
00337                 break;
00338             }
00339         }
00340     }
00341 }
00342 
00343 void StockDiagram::resize( const QSizeF &size )
00344 {
00345     d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
00346                                  static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
00347     setDataBoundariesDirty();
00348 }
00349 
00350 qreal StockDiagram::threeDItemDepth( int column ) const
00351 {
00352     Q_UNUSED( column );
00353     //FIXME: Implement threeD functionality
00354     return 1.0;
00355 }
00356 
00357 qreal StockDiagram::threeDItemDepth( const QModelIndex &index ) const
00358 {
00359     Q_UNUSED( index );
00360     //FIXME: Implement threeD functionality
00361     return 1.0;
00362 }
00363 
00364 const QPair<QPointF, QPointF> StockDiagram::calculateDataBoundaries() const
00365 {
00366     const int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
00367     const int colCount = attributesModel()->columnCount( attributesModelRootIndex() );
00368     qreal xMin = 0.0;
00369     qreal xMax = rowCount;
00370     qreal yMin = 0.0;
00371     qreal yMax = 0.0;
00372     for ( int row = 0; row < rowCount; row++ ) {
00373         for ( int col = 0; col < colCount; col++ ) {
00374             const CartesianDiagramDataCompressor::CachePosition pos( row, col );
00375             const CartesianDiagramDataCompressor::DataPoint point = d->compressor.data( pos );
00376             yMax = qMax( yMax, point.value );
00377             yMin = qMin( yMin, point.value ); // FIXME: Can stock charts really have negative values?
00378         }
00379     }
00380     return QPair<QPointF, QPointF>( QPointF( xMin, yMin ), QPointF( xMax, yMax ) );
00381 }
00382 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines

Klarälvdalens Datakonsult AB (KDAB)
Qt-related services and products
http://www.kdab.com/
http://www.kdab.com/products/kd-chart/