KDChartStockDiagram.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (C) 2001-2011 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 
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     // Set properties to defaults
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     //setDatasetDimension( 3 );
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     // Clear old reverse mapping data and create new
00291     // reverse mapping scene
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                 // Fall-through intended!
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     //FIXME: Implement threeD functionality
00353     return 1.0;
00354 }
00355 
00356 double StockDiagram::threeDItemDepth( const QModelIndex &index ) const
00357 {
00358     Q_UNUSED( index );
00359     //FIXME: Implement threeD functionality
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 ); // FIXME: Can stock charts really have negative values?
00377         }
00378     }
00379     return QPair<QPointF, QPointF>( QPointF( xMin, yMin ), QPointF( xMax, yMax ) );
00380 }
00381 
 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/