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( 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, points,
00180 autoPositionPositive, autoPositionNegative, value );
00181 }
00182
00183 void BarDiagram::BarDiagramType::paintDataValueTextsAndMarkers(
00184 AbstractDiagram* diagram,
00185 PaintContext* ctx,
00186 const DataValueTextInfoList & list,
00187 bool paintMarkers )
00188 {
00189 m_private->paintDataValueTextsAndMarkers( diagram, ctx, list, paintMarkers );
00190 }
00191
00192
00193 void BarDiagram::BarDiagramType::calculateValueAndGapWidths( int rowCount,int colCount,
00194 double groupWidth,
00195 double& outBarWidth,
00196 double& outSpaceBetweenBars,
00197 double& outSpaceBetweenGroups )
00198 {
00199
00200 Q_UNUSED( rowCount );
00201
00202 BarAttributes ba = diagram()->barAttributes( diagram()->model()->index( 0, 0, diagram()->rootIndex() ) );
00203
00204
00205
00206
00207
00208
00209
00210
00211 double units;
00212 if( type() == Normal )
00213 units = colCount
00214 + (colCount-1) * ba.barGapFactor()
00215 + 1 * ba.groupGapFactor();
00216 else
00217 units = 1 + 1 * ba.groupGapFactor();
00218
00219 double unitWidth = groupWidth / units;
00220 outBarWidth = unitWidth;
00221 outSpaceBetweenBars += unitWidth * ba.barGapFactor();
00222
00223
00224 if ( outSpaceBetweenBars < 0 )
00225 outSpaceBetweenBars = 0;
00226
00227 outSpaceBetweenGroups += unitWidth * ba.groupGapFactor();
00228 }
00229
00230 ReverseMapper& BarDiagram::BarDiagramType::reverseMapper()
00231 {
00232 return m_private->reverseMapper;
00233 }
00234
00235 CartesianDiagramDataCompressor& BarDiagram::BarDiagramType::compressor() const
00236 {
00237 return m_private->compressor;
00238 }