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 Q_UNUSED( boundRight )
00058
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
00082
00083
00084 if ( isoRect.height() < 0 ) {
00085 topPoints << isoRect.bottomLeft() << isoRect.bottomRight()
00086 << bar.bottomRight() << bar.bottomLeft();
00087 if ( stackedMode ) {
00088
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
00108
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
00146
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
00200
00201
00202
00203
00204
00205
00206 double units;
00207 if( type() == Normal )
00208 units = colCount
00209 + (colCount-1) * ba.barGapFactor()
00210 + 1 * ba.groupGapFactor();
00211 else
00212 units = 1 + 1 * ba.groupGapFactor();
00213
00214 double unitWidth = groupWidth / units;
00215 outBarWidth = unitWidth;
00216 outSpaceBetweenBars += unitWidth * ba.barGapFactor();
00217
00218
00219
00220
00221
00222
00223
00224
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 }