KD Chart 2 [rev.2.4]

KDChartBarDiagram_p.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 "KDChartBarDiagram.h"
00024 #include "KDChartDataValueAttributes.h"
00025 
00026 #include "KDChartBarDiagram_p.h"
00027 
00028 using namespace KDChart;
00029 
00030 BarDiagram::Private::Private( const Private& rhs )
00031     : AbstractCartesianDiagram::Private( rhs )
00032 {
00033 }
00034 
00035 void BarDiagram::BarDiagramType::paintBars( PaintContext* ctx, const QModelIndex& index, const QRectF& bar, double& maxDepth )
00036 {
00037     QRectF isoRect;
00038     QPolygonF topPoints, sidePoints;
00039     ThreeDBarAttributes threeDAttrs = diagram()->threeDBarAttributes( index );
00040     double usedDepth = 0;
00041 
00042     //Pending Michel: configure threeDBrush settings - shadowColor etc...
00043     QBrush indexBrush ( diagram()->brush( index ) );
00044     QPen indexPen( diagram()->pen( index ) );
00045     PainterSaver painterSaver( ctx->painter() );
00046     if ( diagram()->antiAliasing() )
00047         ctx->painter()->setRenderHint ( QPainter::Antialiasing );
00048     ctx->painter()->setBrush( indexBrush );
00049     ctx->painter()->setPen( PrintingParameters::scalePen( indexPen ) );
00050     if ( threeDAttrs.isEnabled() ) {
00051         bool stackedMode = false;
00052         bool percentMode = false;
00053         bool paintTop = true;
00054         if ( maxDepth )
00055             threeDAttrs.setDepth( -maxDepth );
00056         //fixme adjust the painting to reasonable depth value
00057         switch ( type() )
00058         {
00059         case BarDiagram::Normal:
00060             usedDepth = threeDAttrs.depth()/4;
00061             stackedMode = false;
00062             percentMode = false;
00063             break;
00064         case BarDiagram::Stacked:
00065             usedDepth = threeDAttrs.depth();
00066             stackedMode = true;
00067             percentMode = false;
00068             break;
00069         case BarDiagram::Percent:
00070             usedDepth = threeDAttrs.depth();
00071             stackedMode = false;
00072             percentMode = true;
00073             break;
00074         default:
00075             Q_ASSERT_X ( false, "dataBoundaries()",
00076                          "Type item does not match a defined bar chart Type." );
00077         }
00078         isoRect = bar.translated( usedDepth, -usedDepth );
00079         // we need to find out if the height is negative
00080         // and in this case paint it up and down
00081         //qDebug() << isoRect.height();
00082         if (  isoRect.height() < 0 ) {
00083           topPoints << isoRect.bottomLeft() << isoRect.bottomRight()
00084                     << bar.bottomRight() << bar.bottomLeft();
00085           if ( stackedMode ) {
00086               // fix it when several negative stacked values
00087               if (  index.column() == 0 ) {
00088                   paintTop = true;
00089               }
00090               else
00091                   paintTop = false;
00092           }
00093 
00094         } else {
00095             reverseMapper().addRect( index.row(), index.column(), isoRect );
00096             ctx->painter()->drawRect( isoRect );
00097             topPoints << bar.topLeft() << bar.topRight() << isoRect.topRight() << isoRect.topLeft();
00098         }
00099 
00100         if ( percentMode && isoRect.height() == 0 )
00101             paintTop = false;
00102 
00103         bool needToSetClippingOffForTop = false;
00104         if ( paintTop ){
00105             // Draw the top, if at least one of the top's points is
00106             // either inside or near at the edge of the coordinate plane:
00107             bool drawIt = false;
00108             bool hasPointOutside = false;
00109             const QRectF r( ctx->rectangle().adjusted(0,-1,1,0) );
00110             KDAB_FOREACH( QPointF pt, topPoints ) {
00111                 if( r.contains( pt ) )
00112                     drawIt = true;
00113                 else
00114                     hasPointOutside = true;
00115             }
00116             if( drawIt ){
00117                 const PainterSaver p( ctx->painter() );
00118                 needToSetClippingOffForTop = hasPointOutside && ctx->painter()->hasClipping();
00119                 if( needToSetClippingOffForTop )
00120                     ctx->painter()->setClipping( false );
00121                 reverseMapper().addPolygon( index.row(), index.column(), topPoints );
00122                 ctx->painter()->drawPolygon( topPoints );
00123             }
00124         }
00125 
00126 
00127 
00128         sidePoints << bar.topRight() << isoRect.topRight() << isoRect.bottomRight() << bar.bottomRight();
00129         if (  bar.height() != 0 ){
00130             const PainterSaver p( ctx->painter() );
00131             if( needToSetClippingOffForTop )
00132                 ctx->painter()->setClipping( false );
00133             reverseMapper().addPolygon( index.row(), index.column(), sidePoints );
00134             ctx->painter()->drawPolygon( sidePoints );
00135         }
00136     }
00137 
00138     if( bar.height() != 0 )
00139     {
00140         reverseMapper().addRect( index.row(), index.column(), bar );
00141         ctx->painter()->drawRect( bar );
00142     }
00143     // reset
00144     //diagram()->maxDepth = threeDAttrs.depth();
00145 }
00146 
00147 AttributesModel* BarDiagram::BarDiagramType::attributesModel() const
00148 {
00149     return m_private->attributesModel;
00150 }
00151 
00152 QModelIndex BarDiagram::BarDiagramType::attributesModelRootIndex() const
00153 {
00154     return m_private->diagram->attributesModelRootIndex();
00155 }
00156 
00157 BarDiagram* BarDiagram::BarDiagramType::diagram() const
00158 {
00159     return m_private->diagram;
00160 }
00161 
00162 void BarDiagram::BarDiagramType::appendDataValueTextInfoToList(
00163             AbstractDiagram * diagram,
00164             DataValueTextInfoList & list,
00165             const QModelIndex & index,
00166             const PositionPoints& points,
00167             const Position& autoPositionPositive,
00168             const Position& autoPositionNegative,
00169             const qreal value )
00170 {
00171     m_private->appendDataValueTextInfoToList( diagram, list, index, 0,
00172                                               points,
00173                                               autoPositionPositive, autoPositionNegative, value );
00174 }
00175 
00176 void BarDiagram::BarDiagramType::paintDataValueTextsAndMarkers(
00177     AbstractDiagram* diagram,
00178     PaintContext* ctx,
00179     const DataValueTextInfoList & list,
00180     bool paintMarkers )
00181 {
00182     m_private->paintDataValueTextsAndMarkers( diagram, ctx, list, paintMarkers );
00183 }
00184 
00185 
00186 void BarDiagram::BarDiagramType::calculateValueAndGapWidths( int rowCount,int colCount,
00187                                              double groupWidth,
00188                                              double& outBarWidth,
00189                                              double& outSpaceBetweenBars,
00190                                              double& outSpaceBetweenGroups )
00191 {
00192 
00193     Q_UNUSED( rowCount );
00194 
00195     BarAttributes ba = diagram()->barAttributes( diagram()->model()->index( 0, 0, diagram()->rootIndex() ) );
00196 
00197     // Pending Michel Fixme
00198     /* We are colCount groups to paint. Each group is centered around the
00199      * horizontal point position on the grid. The full area covers the
00200      * values -1 to colCount + 1. A bar has a relative width of one unit,
00201      * the gaps between bars are 0.5 wide, and the gap between groups is
00202      * also one unit, by default. */
00203 
00204     double units;
00205     if( type() == Normal )
00206         units = colCount // number of bars in group * 1.0
00207                 + (colCount-1) * ba.barGapFactor() // number of bar gaps
00208                 + 1 * ba.groupGapFactor(); // number of group gaps
00209     else
00210         units = 1 + 1 * ba.groupGapFactor();
00211 
00212     double unitWidth = groupWidth / units;
00213     outBarWidth = unitWidth;
00214     outSpaceBetweenBars += unitWidth * ba.barGapFactor();
00215 
00216     // Pending Michel - minLimit: allow space between bars to be reduced until the bars are displayed next to each other.
00217     // is that what we want?
00218     // sebsauer; in the case e.g. CartesianCoordinatePlane::setHorizontalRangeReversed(true) was
00219     // used to reverse the values, we deal with negative outSpaceBetweenBars and unitWidth here
00220     // and since that's correct we don't like to lose e.g. the spacing here.
00221     //if ( outSpaceBetweenBars < 0 )
00222     //    outSpaceBetweenBars = 0;
00223 
00224     outSpaceBetweenGroups += unitWidth * ba.groupGapFactor();
00225 }
00226 
00227 ReverseMapper& BarDiagram::BarDiagramType::reverseMapper()
00228 {
00229     return m_private->reverseMapper;
00230 }
00231 
00232 CartesianDiagramDataCompressor& BarDiagram::BarDiagramType::compressor() const
00233 {
00234     return m_private->compressor;
00235 }
 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/