00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
00058 switch ( type() )
00059 {
00060 case BarDiagram::Normal:
00061 usedDepth = threeDAttrs.depth()/4;
00062 stackedMode = false;
00063 percentMode = false;
00064 break;
00065 case BarDiagram::Stacked:
00066 usedDepth = threeDAttrs.depth();
00067 stackedMode = true;
00068 percentMode = false;
00069 break;
00070 case BarDiagram::Percent:
00071 usedDepth = threeDAttrs.depth();
00072 stackedMode = false;
00073 percentMode = true;
00074 break;
00075 default:
00076 Q_ASSERT_X ( false, "dataBoundaries()",
00077 "Type item does not match a defined bar chart Type." );
00078 }
00079 isoRect = bar.translated( usedDepth, -usedDepth );
00080
00081
00082
00083 if ( isoRect.height() < 0 ) {
00084 topPoints << isoRect.bottomLeft() << isoRect.bottomRight()
00085 << bar.bottomRight() << bar.bottomLeft();
00086 if ( stackedMode ) {
00087
00088 if ( index.column() == 0 ) {
00089 paintTop = true;
00090 }
00091 else
00092 paintTop = false;
00093 }
00094
00095 } else {
00096 reverseMapper().addRect( index.row(), index.column(), isoRect );
00097 ctx->painter()->drawRect( isoRect );
00098 topPoints << bar.topLeft() << bar.topRight() << isoRect.topRight() << isoRect.topLeft();
00099 }
00100
00101 if ( percentMode && isoRect.height() == 0 )
00102 paintTop = false;
00103
00104 bool needToSetClippingOffForTop = false;
00105 if ( paintTop ){
00106
00107
00108 bool drawIt = false;
00109 bool hasPointOutside = false;
00110 const QRectF r( ctx->rectangle().adjusted(0,-1,1,0) );
00111 KDAB_FOREACH( QPointF pt, topPoints ) {
00112 if( r.contains( pt ) )
00113 drawIt = true;
00114 else
00115 hasPointOutside = true;
00116 }
00117 if( drawIt ){
00118 const PainterSaver p( ctx->painter() );
00119 needToSetClippingOffForTop = hasPointOutside && ctx->painter()->hasClipping();
00120 if( needToSetClippingOffForTop )
00121 ctx->painter()->setClipping( false );
00122 reverseMapper().addPolygon( index.row(), index.column(), topPoints );
00123 ctx->painter()->drawPolygon( topPoints );
00124 }
00125 }
00126
00127
00128
00129 sidePoints << bar.topRight() << isoRect.topRight() << isoRect.bottomRight() << bar.bottomRight();
00130 if ( bar.height() != 0 ){
00131 const PainterSaver p( ctx->painter() );
00132 if( needToSetClippingOffForTop )
00133 ctx->painter()->setClipping( false );
00134 reverseMapper().addPolygon( index.row(), index.column(), sidePoints );
00135 ctx->painter()->drawPolygon( sidePoints );
00136 }
00137 }
00138
00139 if( bar.height() != 0 )
00140 {
00141 reverseMapper().addRect( index.row(), index.column(), bar );
00142 ctx->painter()->drawRect( bar );
00143 }
00144
00145
00146 }
00147
00148 AttributesModel* BarDiagram::BarDiagramType::attributesModel() const
00149 {
00150 return m_private->attributesModel;
00151 }
00152
00153 QModelIndex BarDiagram::BarDiagramType::attributesModelRootIndex() const
00154 {
00155 return m_private->diagram->attributesModelRootIndex();
00156 }
00157
00158 BarDiagram* BarDiagram::BarDiagramType::diagram() const
00159 {
00160 return m_private->diagram;
00161 }
00162
00163 void BarDiagram::BarDiagramType::appendDataValueTextInfoToList(
00164 AbstractDiagram * diagram,
00165 DataValueTextInfoList & list,
00166 const QModelIndex & index,
00167 const PositionPoints& points,
00168 const Position& autoPositionPositive,
00169 const Position& autoPositionNegative,
00170 const qreal value )
00171 {
00172 m_private->appendDataValueTextInfoToList( diagram, list, index, 0,
00173 points,
00174 autoPositionPositive, autoPositionNegative, value );
00175 }
00176
00177 void BarDiagram::BarDiagramType::paintDataValueTextsAndMarkers(
00178 AbstractDiagram* diagram,
00179 PaintContext* ctx,
00180 const DataValueTextInfoList & list,
00181 bool paintMarkers )
00182 {
00183 m_private->paintDataValueTextsAndMarkers( diagram, ctx, list, paintMarkers );
00184 }
00185
00186
00187 void BarDiagram::BarDiagramType::calculateValueAndGapWidths( int rowCount,int colCount,
00188 double groupWidth,
00189 double& outBarWidth,
00190 double& outSpaceBetweenBars,
00191 double& outSpaceBetweenGroups )
00192 {
00193
00194 Q_UNUSED( rowCount );
00195
00196 BarAttributes ba = diagram()->barAttributes( diagram()->model()->index( 0, 0, diagram()->rootIndex() ) );
00197
00198
00199
00200
00201
00202
00203
00204
00205 double units;
00206 if( type() == Normal )
00207 units = colCount
00208 + (colCount-1) * ba.barGapFactor()
00209 + 1 * ba.groupGapFactor();
00210 else
00211 units = 1 + 1 * ba.groupGapFactor();
00212
00213 double unitWidth = groupWidth / units;
00214 outBarWidth = unitWidth;
00215 outSpaceBetweenBars += unitWidth * ba.barGapFactor();
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 outSpaceBetweenGroups += unitWidth * ba.groupGapFactor();
00226 }
00227
00228 ReverseMapper& BarDiagram::BarDiagramType::reverseMapper()
00229 {
00230 return m_private->reverseMapper;
00231 }
00232
00233 CartesianDiagramDataCompressor& BarDiagram::BarDiagramType::compressor() const
00234 {
00235 return m_private->compressor;
00236 }