00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "KDChartBarDiagram.h"
00031 #include "KDChartDataValueAttributes.h"
00032
00033 #include "KDChartBarDiagram_p.h"
00034
00035 using namespace KDChart;
00036
00037 BarDiagram::Private::Private( const Private& rhs )
00038 : AbstractCartesianDiagram::Private( rhs )
00039 {
00040 }
00041
00042 void BarDiagram::BarDiagramType::paintBars( PaintContext* ctx, const QModelIndex& index, const QRectF& bar, double& maxDepth )
00043 {
00044 QRectF isoRect;
00045 QPolygonF topPoints, sidePoints;
00046 ThreeDBarAttributes threeDAttrs = diagram()->threeDBarAttributes( index );
00047 double usedDepth;
00048
00049
00050 QBrush indexBrush ( diagram()->brush( index ) );
00051 QPen indexPen( diagram()->pen( index ) );
00052 PainterSaver painterSaver( ctx->painter() );
00053 if ( diagram()->antiAliasing() )
00054 ctx->painter()->setRenderHint ( QPainter::Antialiasing );
00055 ctx->painter()->setBrush( indexBrush );
00056 ctx->painter()->setPen( PrintingParameters::scalePen( indexPen ) );
00057 if ( threeDAttrs.isEnabled() ) {
00058 bool stackedMode = false;
00059 bool percentMode = false;
00060 bool paintTop = true;
00061 if ( maxDepth )
00062 threeDAttrs.setDepth( -maxDepth );
00063 QPointF boundRight = ctx->coordinatePlane()->translate( diagram()->dataBoundaries().second );
00064
00065 switch ( type() )
00066 {
00067 case BarDiagram::Normal:
00068 usedDepth = threeDAttrs.depth()/4;
00069 stackedMode = false;
00070 percentMode = false;
00071 break;
00072 case BarDiagram::Stacked:
00073 usedDepth = threeDAttrs.depth();
00074 stackedMode = true;
00075 percentMode = false;
00076 break;
00077 case BarDiagram::Percent:
00078 usedDepth = threeDAttrs.depth();
00079 stackedMode = false;
00080 percentMode = true;
00081 break;
00082 default:
00083 Q_ASSERT_X ( false, "dataBoundaries()",
00084 "Type item does not match a defined bar chart Type." );
00085 }
00086 isoRect = bar.translated( usedDepth, -usedDepth );
00087
00088
00089
00090 if ( isoRect.height() < 0 ) {
00091 topPoints << isoRect.bottomLeft() << isoRect.bottomRight()
00092 << bar.bottomRight() << bar.bottomLeft();
00093 if ( stackedMode ) {
00094
00095 if ( index.column() == 0 ) {
00096 paintTop = true;
00097 }
00098 else
00099 paintTop = false;
00100 }
00101
00102 } else {
00103 reverseMapper().addRect( index.row(), index.column(), isoRect );
00104 ctx->painter()->drawRect( isoRect );
00105 topPoints << bar.topLeft() << bar.topRight() << isoRect.topRight() << isoRect.topLeft();
00106 }
00107
00108 if ( percentMode && isoRect.height() == 0 )
00109 paintTop = false;
00110
00111 bool needToSetClippingOffForTop = false;
00112 if ( paintTop ){
00113
00114
00115 bool drawIt = false;
00116 bool hasPointOutside = false;
00117 const QRectF r( ctx->rectangle().adjusted(0,-1,1,0) );
00118 KDAB_FOREACH( QPointF pt, topPoints ) {
00119 if( r.contains( pt ) )
00120 drawIt = true;
00121 else
00122 hasPointOutside = true;
00123 }
00124 if( drawIt ){
00125 const PainterSaver p( ctx->painter() );
00126 needToSetClippingOffForTop = hasPointOutside && ctx->painter()->hasClipping();
00127 if( needToSetClippingOffForTop )
00128 ctx->painter()->setClipping( false );
00129 reverseMapper().addPolygon( index.row(), index.column(), topPoints );
00130 ctx->painter()->drawPolygon( topPoints );
00131 }
00132 }
00133
00134
00135
00136 sidePoints << bar.topRight() << isoRect.topRight() << isoRect.bottomRight() << bar.bottomRight();
00137 if ( bar.height() != 0 ){
00138 const PainterSaver p( ctx->painter() );
00139 if( needToSetClippingOffForTop )
00140 ctx->painter()->setClipping( false );
00141 reverseMapper().addPolygon( index.row(), index.column(), sidePoints );
00142 ctx->painter()->drawPolygon( sidePoints );
00143 }
00144 }
00145
00146 if( bar.height() != 0 )
00147 {
00148 reverseMapper().addRect( index.row(), index.column(), bar );
00149 ctx->painter()->drawRect( bar );
00150 }
00151
00152
00153 }
00154
00155 AttributesModel* BarDiagram::BarDiagramType::attributesModel() const
00156 {
00157 return m_private->attributesModel;
00158 }
00159
00160 QModelIndex BarDiagram::BarDiagramType::attributesModelRootIndex() const
00161 {
00162 return m_private->diagram->attributesModelRootIndex();
00163 }
00164
00165 BarDiagram* BarDiagram::BarDiagramType::diagram() const
00166 {
00167 return m_private->diagram;
00168 }
00169
00170 void BarDiagram::BarDiagramType::appendDataValueTextInfoToList(
00171 AbstractDiagram * diagram,
00172 DataValueTextInfoList & list,
00173 const QModelIndex & index,
00174 const PositionPoints& points,
00175 const Position& autoPositionPositive,
00176 const Position& autoPositionNegative,
00177 const qreal value )
00178 {
00179 m_private->appendDataValueTextInfoToList( diagram, list, index, 0,
00180 points,
00181 autoPositionPositive, autoPositionNegative, value );
00182 }
00183
00184 void BarDiagram::BarDiagramType::paintDataValueTextsAndMarkers(
00185 AbstractDiagram* diagram,
00186 PaintContext* ctx,
00187 const DataValueTextInfoList & list,
00188 bool paintMarkers )
00189 {
00190 m_private->paintDataValueTextsAndMarkers( diagram, ctx, list, paintMarkers );
00191 }
00192
00193
00194 void BarDiagram::BarDiagramType::calculateValueAndGapWidths( int rowCount,int colCount,
00195 double groupWidth,
00196 double& outBarWidth,
00197 double& outSpaceBetweenBars,
00198 double& outSpaceBetweenGroups )
00199 {
00200
00201 Q_UNUSED( rowCount );
00202
00203 BarAttributes ba = diagram()->barAttributes( diagram()->model()->index( 0, 0, diagram()->rootIndex() ) );
00204
00205
00206
00207
00208
00209
00210
00211
00212 double units;
00213 if( type() == Normal )
00214 units = colCount
00215 + (colCount-1) * ba.barGapFactor()
00216 + 1 * ba.groupGapFactor();
00217 else
00218 units = 1 + 1 * ba.groupGapFactor();
00219
00220 double unitWidth = groupWidth / units;
00221 outBarWidth = unitWidth;
00222 outSpaceBetweenBars += unitWidth * ba.barGapFactor();
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 outSpaceBetweenGroups += unitWidth * ba.groupGapFactor();
00233 }
00234
00235 ReverseMapper& BarDiagram::BarDiagramType::reverseMapper()
00236 {
00237 return m_private->reverseMapper;
00238 }
00239
00240 CartesianDiagramDataCompressor& BarDiagram::BarDiagramType::compressor() const
00241 {
00242 return m_private->compressor;
00243 }