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